수색…


Node.Js의 예외 처리

Node.js에는 예외 / 오류를 처리 할 수있는 3 가지 기본 방법이 있습니다.

  1. try - catch 블록
  2. callback 대한 첫 번째 인수로 오류
  3. emit eventEmitter를 이용한 에러 이벤트

try-catch 는 동기 코드 실행에서 던져진 예외를 잡는 데 사용됩니다. 호출자 (또는 호출자의 호출자)가 try / catch를 사용하면 오류를 catch 할 수 있습니다. 호출자 중 누구도 try-catch를하지 않은 경우 프로그램이 충돌합니다.
비동기 작업에서 try-catch를 사용하고 try-catch가 catch하지 않는 것보다 async 메서드의 콜백에서 예외가 throw 된 경우 비동기 작업 콜백에서 예외를 잡으려면 약속 을 사용하는 것이 좋습니다.
그것을 더 잘 이해하는 예

// ** Example - 1  **
function doSomeSynchronousOperation(req, res) {
    if(req.body.username === ''){
        throw new Error('User Name cannot be empty');
    }  
    return true;  
}

// calling the method above
try {
    // synchronous code   
    doSomeSynchronousOperation(req, res)    
catch(e) {
    //exception handled here   
    console.log(e.message);  
} 

// ** Example - 2 **
function doSomeAsynchronousOperation(req, res, cb) {
    // imitating async operation
    return setTimeout(function(){
        cb(null, []);
    },1000);
}
 
try {
    // asynchronous code   
    doSomeAsynchronousOperation(req, res, function(err, rs){
        throw new Error("async operation exception");
    })   
} catch(e) {
     // Exception will not get handled here
     console.log(e.message);  
}
// The exception is unhandled and hence will cause application to break

콜백 은 이벤트를 비동기 적으로 전달하기 때문에 Node.js에서 주로 사용됩니다. 사용자는 함수 (콜백)를 전달하고 나중에 비동기 작업이 완료 될 때 호출합니다.
통상의 패턴은, 콜백이 콜백 (err, result) 로서 불려갑니다.이 경우, 조작이 성공했는지 실패했는지에 따라, err와 result 중 한쪽 만이 null가 아닙니다.

function doSomeAsynchronousOperation(req, res, callback) {
   setTimeout(function(){
        return callback(new Error('User Name cannot be empty'));    
   }, 1000);  
   return true;
}

doSomeAsynchronousOperation(req, res, function(err, result) {
   if (err) {
       //exception handled here 
       console.log(err.message);
   }
   
   //do some stuff with valid data
});

emit 보다 복잡한 경우 콜백 대신에 함수 자체가 EventEmitter 객체를 반환 할 수 있으며 호출자는 에미 터의 오류 이벤트를 수신해야합니다.

const EventEmitter = require('events');

function doSomeAsynchronousOperation(req, res) {
    let myEvent = new EventEmitter();

    // runs asynchronously
    setTimeout(function(){
        myEvent.emit('error', new Error('User Name cannot be empty'));
    }, 1000);

    return myEvent;
}

// Invoke the function
let event = doSomeAsynchronousOperation(req, res);

event.on('error', function(err) {
    console.log(err);
});

event.on('done', function(result) {
    console.log(result); // true
});

처리되지 않은 예외 관리

Node.js는 단일 프로세스에서 실행되기 때문에 잡히지 않은 예외는 응용 프로그램을 개발할 때 알아야 할 문제입니다.

무음 처리 예외

대부분의 사람들은 node.js 서버가 자동으로 오류를 삼킨다.

  • 자동으로 예외 처리
process.on('uncaughtException', function (err) {
  console.log(err);
});

이것은 나쁘다 , 그것은 작동하지만 :

  • 근본 원인은 알 수없는 상태로 유지되므로 예외 (오류)를 일으킨 원인을 해결하지는 않습니다.

  • 어떤 이유로 데이터베이스 연결 (풀)이 닫히면 오류가 계속 전파되어 서버가 실행 중이지만 db에 다시 연결되지 않습니다.


초기 상태로 돌아 가기

"uncaughtException"의 경우 서버를 다시 시작하고 초기 상태로 돌아가는 것이 좋습니다. 서버가 작동하는 것으로 알고 있습니다. 예외가 기록되고 응용 프로그램이 종료되지만 서버가 실행 중인지 확인하는 컨테이너에서 실행되므로 서버를 다시 시작 (초기 작업 상태로 복귀) 할 수 있습니다.

  • 영원히 (또는 다른 CLI 도구를 설치하여 노드 서버가 계속 실행되는지 확인)
npm install forever -g
  • 영원히 서버 시작하기
forever start app.js

이유는 왜 시작되었고 영원히 사용하는 이유는 서버가 영원히 종료 된 후에 프로세스가 서버를 다시 시작하게하기 때문입니다.

  • 서버 다시 시작
process.on('uncaughtException', function (err) {
    console.log(err);

    // some logging mechanisam
    // ....        

    process.exit(1); // terminates process
});

참고로 클러스터와 도메인을 사용 하여 예외를 처리하는 방법도있었습니다.

도메인은 더 이상 여기에서 더 이상 사용되지 않습니다.

오류와 약속

약속은 동기식 또는 콜백 방식의 코드와 다르게 처리합니다.

const p = new Promise(function (resolve, reject) {
    reject(new Error('Oops'));
});

// anything that is `reject`ed inside a promise will be available through catch
// while a promise is rejected, `.then` will not be called
p
    .then(() => {
        console.log("won't be called");
    })
    .catch(e => {
        console.log(e.message); // output: Oops
    })
    // once the error is caught, execution flow resumes
    .then(() => {
        console.log('hello!'); // output: hello!
    });

현재 잡히지 않은 약속에서 던진 오류는 오류를 삼킨 결과로 오류를 추적하기가 어려울 수 있습니다. 이 할 수 해결 같은 linting 도구를 사용하여 eslint을 하거나 보장함으로써 당신은 항상이 catch 절을.

이 동작은 노드 프로세스를 종료하기 위해 노드 8 에서 더 이상 사용되지 않습니다.



Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow