Node.js에서 연속 전달 스타일의 API 및 콜백은 일련의 특정한 규칙을 따른다. 이 규칙은 Node.js 코어 API에 적용되지만 대다수의 사용자 영역 모듈과 어플리케이션에도 적용된다. 따라서 비동기 API를 설계할 때마다 이를 이해하고 반드시 준수해야 한다.
모든 코어 Node.js 함수에서 표준 규칙은 함수가 입력에서 콜백을 허용했다면 맨 마지막 인자로 전달되어야 한다. 여러 피라미터가 함수에 인자로 정의되었더라도 마지막에 콜백 함수를 위치 시켜야만 한다. 이유는 콜백이 적절한 위치에 정의되어 있어야 함수 호출의 가독성이 더 좋기 때문이다.
CPS에서는 오류가 다른 유형의 결과처럼 전달되므로 콜백 사용이 필요하다. Node.js에서 CPS 함수에 의해 생성된 오류는 항상 콜백의 첫 번째 인수로 전달된다. 실제 결과는 두 번째 인수에서 부터 전달이 되는데 아래의 코드를 보면 이해하기 쉽다.
fetch.then( (err, result) => { console.log(err) } );
동작이 에러 없이 성공했다면 err가 위치한 최초의 인수 위치에는 null 또는 undefine이 정의된다. 한마디로 콜백 함수가 받는 인자의 최초의 인자는 에러코드가 되며 결과 값은 두번째 인자에서부터 시작된다는 말이다.
동기식 직접 스타일 함수의 오류 전파는 잘 알려진 throw 문을 사용하여 수행되므로 오류가 catch 될 때까지 콜 스택에서 실행 된다. 그러나 비동기식 CPS에서 적절한 오류 전달은 오류를 호출 체인의 다음에서 콜백으로 전달하여 수행된다. 무슨 말인가 하면 return 문에 콜백함수를 써서 그 에러를 알려준다는 말이다. 다음 코드를 보면 이해하기 쉽다.
const fs = require('fs') // 파일 읽은 모듈
const readJSON = (filename, callabck) => {
fs.readFile(filename, 'utf-8', (err, data) => {
let parsed;
if(err) return callabck(err)
try{
parsed = JSON.parse(data);
}catch(err){
return callback(err)
}
callback(null, parsed);
})
}
위 코드에서 보았듯이 함수 내 콜백에서 던져지는 에러들을 예외처리 하기 위해서 try와 catch를 사용했다. 비동기 콜백 내부에서 예외를 발생시키면 예외가 이벤트 루프로 이동하여 콜백으로 전달 되지 않는데, 이것은 회복불능 상태라고 한다. 대신 어플리케이션은 그냥 종료가 되며, stderr 인터페이스를 통해 오류가 출력이 되는데 이러한 캐치 되지 않은 예외들을 처리하는 방법은 아래와 같다.
process.on('uncaughtException', (err) => {
console.err('This will catch at last the' + 'JSON parsing exception:' + err.message);
])
이렇게 하면 프로세스가 종료되지 않고 에러를 띄우며 실행은 계속 시킬 수 있다. 만약 캐치되지 않은 에러를 잡았을때 종료하고 싶다면 process.exit(1) 을 아래줄에 추가 해주면 된다. 하지만 잡히지 않았던 예외가 수신 되었다면 항상 어플리케이션을 종료하는 것이 이롭다.