Node.js UnhandledPromiseRejectionWarning에서 처리되지 않은 약속을 찾는 방법은 무엇입니까?


177

버전 7의 Node.js에는 약속을 처리하기위한 비동기 / 대기 구문 설탕이 있으며 이제 내 코드에서 다음 경고가 자주 발생합니다.

(node:11057) UnhandledPromiseRejectionWarning: Unhandled promise 
rejection (rejection id: 1): ReferenceError: Error: Can't set headers 
after they are sent.
(node:11057) DeprecationWarning: Unhandled promise rejections are 
deprecated. In the future, promise rejections that are not handled 
will terminate the Node.js process with a non-zero exit code.

불행히도 캐치가 누락 된 라인에 대한 참조는 없습니다. 모든 try / catch 블록을 확인하지 않고 찾을 수있는 방법이 있습니까?


Bluebird promise 라이브러리를 사용할 수 있으며 스택 추적을 제공 할 수 있습니다.
jfriend00

3
아마도 노드의 unhandledRejection이벤트에 등록 하면 도움이 될까요? 문서를 참조하십시오 . 콜백은 Error객체와 actual을 가져오고 객체 는 스택 추적을 보유 할 수 Promise있다고 생각합니다 Error.
YSK

이전의 두 의견이 도움이되지 않으면 Can't set headers after they are sent.코드에서 발생할 수있는 단서를 제공해야합니다 (예 : 비동기 코드를 이해하지 못했기 때문에 헤더가 이미 전송 된 후 헤더를 설정하는 곳) , 그러나 그것은 추측입니다)
Jaromanda X

안녕하세요, 메시지는 코드에서 버그의 위치를 ​​찾는 데 도움이되지만 라인을 아는 것만 큼 쉽지는 않습니다.
user1658162

1
@ jfriend00 비동기 함수에 오류가 발생하는 상황으로 나타났습니다. 비동기 함수에 대한 내부 노드 약속은 블루 버드를 사용하지 않으므로 해당 시나리오에서 블루 버드가 도움이되지 않습니다.
Adam Reis

답변:


297

unhandledRejection프로세스의 이벤트를 듣 습니다.

process.on('unhandledRejection', (reason, p) => {
  console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
  // application specific logging, throwing an error, or other logic here
});

35
로깅 error.stack(또는 위 예제에서 reason.stack)은 오류의 전체 스택 추적을 제공합니다.
Adam Reis

필자가 찾은 다른 많은 예제들에서 process.on보다 오히려 넣어 주셔서 감사합니다server.on
PhillipHolmes

9
나는 이것이 효과가 있다고 말할 수 있었으면 좋겠다. 노드 8.9.4에 있습니다.
ffxsam

2
위의 코드를 시도했지만 두 가지 이유로 정의되지 않았습니다 .p? 어떤 제안? "처리되지 않은 거부 위치 : 약속 {상태 : '거부 됨', 이유 : 정의되지 않음} 이유 : 정의되지 않음"
Jeremy

3
이 코드를 노드 app.js파일 맨 위에 추가 했는데 불행히도 아무것도 기록되지 않습니다. 노드 v10.13.0.
user1063287

71

올바른 처리되지 않은 ES6 약속 거부에 대한 전체 스택 트레이스를 표시하는 방법으로,과 Node.js를 실행하는 것입니다 --trace-warnings플래그. 이것은 자신의 코드 내에서 거부를 가로 챌 필요없이 모든 경고에 대한 전체 스택 추적을 보여줍니다. 예를 들면 다음과 같습니다.

노드 --trace-warnings app.js

파일 이름 앞에trace-warnings 플래그가 있는지 확인하십시오 ! 그렇지 않으면 플래그는 스크립트에 대한 인수로 해석되며 Node.js 자체에서 무시됩니다..js

처리 되지 않은 거부 를 실제로 처리 하려면 (예 : 로깅) unhandled-rejection모듈을 대신 사용 하면 단일 이벤트 처리기로 모듈을 지원하는 모든 주요 약속 구현에 대해 처리되지 않은 모든 거부를 잡을 수 있습니다.

그 모듈을 지원하는 블루 버드, ES6의 약속, Q, WhenJS, es6-promise, then/promise, 무엇이든 그 처리되지 않은 거부 사양 (문서 전체 세부 사항)의 준수합니다.


20
노드 7.8.0을 사용하면이 모든 것이 내부 노드 모듈에 대한 스택 추적입니다. (node ​​: 10372) UnhandledPromiseRejectionWarning : 처리되지 않은 약속 거부 (거부 ID : 2) : 프로세스의 emitPendingUnhandledRejections (internal / process / promises.js : 86 : 11)에서 emitWarning (internal / process / promises.js : 59 : 21)에 정의되지 않음 ._tickDomainCallback (internal / process / next_tick.js : 136 : 7)
Will Lovett

3
처리되지 않은 약속 문제가 어디에 있는지 보여주는 출력이 표시되지 않습니다.
Jason Leach

package.json스크립트 를 시작 하기 위해 이것을 추가 했지만 불행히도 아무것도 기록되지 않았습니다. 노드 v10.13.0.
user1063287

1
@ user1063287 플래그가 명령에서 올바른 위치에 있는지 확인하십시오. 방금 스크립트 이름 앞에 가야한다는 것을 강조하기 위해 답변에 업데이트를 추가했습니다 .
Sven Slootweg

2
처리되지 않은 원래 오류 ( 더 이상 사용되지 않는 경고 보다 높은 위치)가 아니라 더 이상 사용되지 않는 경고의 스택 추적을보고있을 것 입니다.
Sven Slootweg

7

스택 추적으로 로깅

유용한 오류 메시지가 더있는 경우 이것을 노드 파일에 추가하십시오. 충돌이 발생한 전체 스택 추적을 표시해야합니다.

process.on('unhandledRejection', (error, p) => {
  console.log('=== UNHANDLED REJECTION ===');
  console.dir(error.stack);
});

기능상의 차이점은 오류의 스택 속성에서 console.dir을 수행하는 것입니다. 허용 된 답변과 비교하여 출력의 차이가 큽니다.
joshuakcockrell
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.