[node.js] Node.js + Express.js 애플리케이션에 대한 오류 처리 원리?

Node.js + Express.js 애플리케이션 에서 오류보고 / 처리가 다른 프레임 워크와 다르게 수행되는 것처럼 보입니다 . 그것이 다음과 같이 작동한다는 것을 이해하는 것이 맞습니까?

A) 콜백 함수에 대한 매개 변수로 오류를 수신하여 오류를 감지 하십시오. 예를 들면 다음과 같습니다.

doSomethingAndRunCallback(function(err) { 
    if(err) {  }
});

B) next (err)를 호출하여 MIDDLEWARE의 오류를 보고하십시오 . 예:

handleRequest(req, res, next) {
    // An error occurs…
    next(err);
}

C) 오류를 발생시켜 ROUTES에 오류를 보고 하십시오. 예:

app.get('/home', function(req, res) {
    // An error occurs
    throw err;
});

D) 핸들 app.error를 통해 자신의 오류 처리기를 구성하여 오류 () 또는 일반 연결 오류 처리기를 사용합니다. 예:

app.error(function(err, req, res, next) {
    console.error(err);
    res.send('Fail Whale, yo.');
});

이 네 가지 원칙이 Node.js + Express.js 애플리케이션의 모든 오류 처리 /보고에 대한 기초입니까?



답변

Node.js의 오류 처리는 일반적으로 A) 형식입니다. 대부분의 콜백은 오류 객체를 첫 번째 인수 또는로 반환합니다 null.

Express.js는 미들웨어를 사용하고 미들웨어 구문은 B) 및 E)를 사용합니다 (아래 참조).

C) 나에게 묻는다면 나쁜 습관이다.

app.get('/home', function(req, res) {
    // An error occurs
    throw err;
});

위와 같이 쉽게 위의 내용을 다시 쓸 수 있습니다

app.get('/home', function(req, res, next) {
    // An error occurs
    next(err);
});

미들웨어 구문은 get요청 에서 유효합니다 .

D는)

(07:26:37 PM) tjholowaychuk : app.error가 3.x에서 제거되었습니다

TJ는 방금 app.errorE에 찬성하여 더 이상 사용되지 않음을 확인했습니다.

이자형)

app.use(function(err, req, res, next) {
  // Only handle `next(err)` calls
});

길이가 4 (4 개의 인수) 인 미들웨어는 오류 미들웨어로 간주됩니다. 하나의 호출이 next(err)연결되면 오류 기반 미들웨어를 호출합니다.


답변

Joyent의 사람들은 이것에 대한 정말 통찰력있는 모범 사례 문서 를 발표했습니다. Node.js 개발자를위한 필수 기사입니다.


답변

왜 첫 번째 매개 변수입니까?

Node.js의 비동기 특성으로 인해 first-parameter-as-err 패턴은 userland Node.js 오류 처리 규칙으로 잘 확립되었습니다 . 비동기이기 때문입니다.

try {
    setTimeout(function() {
        throw 'something broke' //Some random error
    }, 5)
}
catch(e) {
   //Will never get caught
}

따라서 콜백의 첫 번째 인수를 갖는 것이 오류를 던지는 것 이외의 비동기식으로 오류를 전달할 수있는 유일한 방법입니다.

그렇게하면 unhandled exception소리가 나는 방식으로 응용 프로그램을 혼란 상태에서 벗어나기 위해 수행 된 작업이 없음을 의미합니다.

예외, 왜 존재 하는가

그러나 Node.js의 거의 모든 부분이 이벤트 이미 터이고 예외가 발생하면 모든 이벤트처럼 처리 할 수있는 저수준 이벤트라는 점에 주목할 가치가 있습니다.

//This won't immediately crash if connection fails
var socket = require("net").createConnection(5000);
socket.on("error", function(err) {
    console.error("calm down...", err)
});

이것은 -하지만 박사 – 수 있는 극단적으로 취할 수 있는 모든 오류를 포착 하고 열심히 충돌하지하려고합니다 응용 프로그램을 확인합니다. 거의 모든 유스 케이스에서 끔찍한 아이디어입니다. 애플리케이션 상태에서 무슨 일이 일어나고 있는지 전혀 알지 못하고 개발자를 try-catch로 감싸는 것과 비슷하기 때문에 개발자를 떠날 것입니다.

도메인-이벤트를 논리적으로 그룹화

이러한 예외 문제를 해결하는 응용 프로그램 문제의 일부로 개발자는 도메인을 통해 예를 들어 Express.js 응용 프로그램을 사용하여 치명적인 오류가 발생했을 때 현명하게 연결을 끊을 수 있습니다.

ES6

ES6에서 생성기 패턴이 try / catch 블록으로 여전히 캐치 할 수있는 비동기 이벤트를 생성 할 수 있기 때문에 이것이 다시 변경 될 것이라고 언급하고있을 것입니다.

Koa (TJ Holowaychuck, Express.js의 동일한 저자)가이 작업을 눈에 띄게 수행합니다. ES6 yield문을 사용하여 거의 동 기적으로 보이지만 일반적인 노드 비동기 방식으로 처리되는 블록을 만듭니다.

app.use(function *(next) {
    try {
        yield next;
    } 
    catch (err) {
        this.status = err.status || 500;
        this.body = err.message;
        this.app.emit('error', err, this);
    }
});

app.use(function *(next) {
    throw new Error('some error');
})

이 예는 여기서 뻔뻔스럽게 도난당했습니다 .


답변