728x90
반응형
질문 : Node.js 모범 사례 예외 처리
며칠 전에 node.js를 사용해보기 시작했습니다. 내 프로그램에서 처리되지 않은 예외가있을 때마다 노드가 종료된다는 것을 깨달았습니다. 이것은 처리되지 않은 예외가 발생하고 컨테이너가 여전히 요청을받을 수있을 때 작업자 스레드 만 죽는 일반적인 서버 컨테이너와 다릅니다. 이것은 몇 가지 질문을 제기합니다.
process.on('uncaughtException')
를 방지하는 유일한 효과적인 방법입니까?process.on('uncaughtException')
은 비동기 프로세스 실행 중에도 처리되지 않은 예외를 포착합니까?- 잡히지 않은 예외의 경우에 활용할 수있는 이미 빌드 된 모듈 (예 : 이메일 보내기 또는 파일 쓰기)이 있습니까?
node.js에서 잡히지 않은 예외를 처리하기위한 일반적인 모범 사례를 보여주는 포인터 / 기사에 감사드립니다.
답변
업데이트 : Joyent는 이제 자체 가이드를 가지고 있습니다. 다음 정보는 요약에 가깝습니다.
이상적으로 우리는 가능한 한 포착되지 않은 오류를 피하고 싶습니다. 문자 그대로 오류를 던지는 대신 코드 아키텍처에 따라 다음 방법 중 하나를 사용하여 오류를 안전하게 "던질"할 수 있습니다.
- 동기 코드의 경우 오류가 발생하면 오류를 반환합니다.
// Define divider as a syncrhonous function var divideSync = function(x,y) { // if error condition? if ( y === 0 ) { // "throw" the error safely by returning it return new Error("Can't divide by zero") } else { // no error occured, continue on return x/y } } // Divide 4/2 var result = divideSync(4,2) // did an error occur? if ( result instanceof Error ) { // handle the error safely console.log('4/2=err', result) } else { // no error occured, continue on console.log('4/2='+result) } // Divide 4/0 result = divideSync(4,0) // did an error occur? if ( result instanceof Error ) { // handle the error safely console.log('4/0=err', result) } else { // no error occured, continue on console.log('4/0='+result) }
- 콜백 기반 (예. 비동기) 코드의 경우, 콜백의 첫 번째 인수는
err
오류가 발생하는 경우,err
오류가 다음 발생하지 않을 경우, 오류입니다err
이다null
. 다른 모든 인수는err
인수를 따릅니다.var divide = function(x,y,next) { // if error condition? if ( y === 0 ) { // "throw" the error safely by calling the completion callback // with the first argument being the error next(new Error("Can't divide by zero")) } else { // no error occured, continue on next(null, x/y) } } divide(4,2,function(err,result){ // did an error occur? if ( err ) { // handle the error safely console.log('4/2=err', err) } else { // no error occured, continue on console.log('4/2='+result) } }) divide(4,0,function(err,result){ // did an error occur? if ( err ) { // handle the error safely console.log('4/0=err', err) } else { // no error occured, continue on console.log('4/0='+result) } })
- 오류가 발생할 수있는 이벤트가 많은 코드의 경우 오류를 발생시키는
error
이벤트를 대신 발생시킵니다.// Definite our Divider Event Emitter var events = require('events') var Divider = function(){ events.EventEmitter.call(this) } require('util').inherits(Divider, events.EventEmitter) // Add the divide function Divider.prototype.divide = function(x,y){ // if error condition? if ( y === 0 ) { // "throw" the error safely by emitting it var err = new Error("Can't divide by zero") this.emit('error', err) } else { // no error occured, continue on this.emit('divided', x, y, x/y) } // Chain return this; } // Create our divider and listen for errors var divider = new Divider() divider.on('error', function(err){ // handle the error safely console.log(err) }) divider.on('divided', function(x,y,result){ console.log(x+'/'+y+'='+result) }) // Divide divider.divide(4,2).divide(4,0)// Definite our Divider Event Emitter var events = require('events') var Divider = function(){ events.EventEmitter.call(this) } require('util').inherits(Divider, events.EventEmitter) // Add the divide function Divider.prototype.divide = function(x,y){ // if error condition? if ( y === 0 ) { // "throw" the error safely by emitting it var err = new Error("Can't divide by zero") this.emit('error', err) } else { // no error occured, continue on this.emit('divided', x, y, x/y) } // Chain return this; } // Create our divider and listen for errors var divider = new Divider() divider.on('error', function(err){ // handle the error safely console.log(err) }) divider.on('divided', function(x,y,result){ console.log(x+'/'+y+'='+result) }) // Divide divider.divide(4,2).divide(4,0)
하지만 가끔 어딘가에 오류를 발생시키는 코드가 여전히있을 수 있습니다.이 코드는 포착되지 않은 예외로 이어질 수 있으며 안전하게 포착하지 못하면 애플리케이션이 충돌 할 수 있습니다. 코드 아키텍처에 따라 다음 방법 중 하나를 사용하여이를 포착 할 수 있습니다.
- 오류가 발생한 위치를 알고 있으면 해당 섹션을 node.js 도메인에 래핑 할 수 있습니다.
var d = require('domain').create() d.on('error', function(err){ // handle the error safely console.log(err) }) // catch the uncaught errors in this asynchronous or synchronous code block d.run(function(){ // the asynchronous or synchronous code that we want to catch thrown errors on var err = new Error('example') throw err })
- 오류가 발생한 위치가 동기 코드이고 어떤 이유로 든 도메인을 사용할 수없는 경우 (아마도 이전 버전의 노드) try catch 문을 사용할 수 있습니다.
그러나 비동기 적으로 발생한 오류는 포착되지 않으므로 비동기 코드에서// catch the uncaught errors in this synchronous code block // try catch statements only work on synchronous code try { // the synchronous code that we want to catch thrown errors on var err = new Error('example') throw err } catch (err) { // handle the error safely console.log(err) }
try...catch
를 사용하지 않도록주의하십시오.try { setTimeout(function(){ var err = new Error('example') throw err }, 1000) } catch (err) { // Example error won't be caught here... crashing our app // hence the need for domains }
try..catch
로 작업하려면 Node 7.4 이상을 실행할 때async/await
사용하여 비동기 함수를 작성할 수 있습니다.try...catch
주의해야 할 또 다른 사항은 다음과 같이try
문 내부에서 완료 콜백을 래핑 할 위험이 있다는 것입니다.
이 문제는 코드가 더 복잡 해짐에 따라 수행하기 매우 쉽습니다. 따라서 도메인을 사용하거나 오류를 반환하여 (1) 비동기 코드에서 포착되지 않은 예외를 피하고 (2) 원하지 않는 실행 포착 시도를 방지하는 것이 가장 좋습니다. JavaScript의 비동기 이벤트 머신 스타일 대신 적절한 스레딩을 허용하는 언어에서는 이는 문제가되지 않습니다.var divide = function(x,y,next) { // if error condition? if ( y === 0 ) { // "throw" the error safely by calling the completion callback // with the first argument being the error next(new Error("Can't divide by zero")) } else { // no error occured, continue on next(null, x/y) } } var continueElsewhere = function(err, result){ throw new Error('elsewhere has failed') } try { divide(4, 2, continueElsewhere) // ^ the execution of divide, and the execution of // continueElsewhere will be inside the try statement } catch (err) { console.log(err.stack) // ^ will output the "unexpected" result of: elsewhere has failed }
- 마지막으로, 도메인이나 try catch 문에 래핑되지 않은 위치에서 포착되지 않은 오류가 발생하는 경우
uncaughtException
리스너를 사용하여 애플리케이션이 충돌하지 않도록 할 수 있습니다 (하지만 그렇게하면 애플리케이션이 알려지지 않은 상태에 놓일 수 있음). 주 ) :// catch the uncaught errors that weren't wrapped in a domain or try catch statement // do not use this in modules, but only in applications, as otherwise we could have multiple of these bound process.on('uncaughtException', function(err) { // handle the error safely console.log(err) }) // the asynchronous or synchronous code that emits the otherwise uncaught error var err = new Error('example') throw err
출처 : https://stackoverflow.com/questions/7310521/node-js-best-practice-exception-handling
728x90
반응형
'프로그래밍 언어 > HTML,CSS,JS' 카테고리의 다른 글
Node.js에서“ReferenceError : primordials is not defined”수정 방법 (0) | 2021.07.09 |
---|---|
CSS 선택기 중 "+"(더하기 기호)가 의미하는 것 (0) | 2021.07.08 |
CSS calc () 함수의 Sass 변수 (0) | 2021.07.08 |
요소 전용 CSS 스타일 재설정 / 제거 (0) | 2021.07.07 |
정적 HTML 페이지에 파비콘 추가 하는 방법 (0) | 2021.07.07 |