약속 삼키는 오류를 방지하는 방법

비동기 코드를 사용하는 동안 JavaScript의 ES6 약속은 두 번째 줄마다 콜백 피라미드와 오류 처리 없이 삶을 훨씬 쉽게 만들 수 있습니다. 그러나 약속에는 몇 가지 함정이 있으며 가장 큰 함정은 기본적으로 오류를 삼키는 것입니다.
아래의 모든 경우에 대해 콘솔에 오류를 인쇄할 것으로 예상한다고 가정해 보겠습니다.

Promise.resolve("promised value").then(function () {
  throw new Error("error");
});

Promise.reject("error value").catch(function () {
  throw new Error("error");
});

new Promise(function (resolve, reject) {
  throw new Error("error");
});


그러나 어떤 오류도 출력하지 않는 최신 JavaScript 환경이 많이 있습니다. 다양한 방법으로 이 문제를 해결할 수 있습니다.

1. 각 체인 끝에 캐치 블록 추가
각 약속 체인의 끝에 catch 블록을 추가할 수 있습니다.

Promise.resolve("promised value")
  .then(function () {
    throw new Error("error");
  })
  .catch(function (error) {
    console.error(error.stack);
  });


그러나 각각의 Promise Chain과 Verbose를 입력하는 것은 매우 어렵습니다.

2.** done 메소드 추가**
첫 번째 솔루션의 then 및 catch 블록을 done 메서드로 바꿀 수 있습니다.

Promise.resolve("promised value").done(function () {
  throw new Error("error");
});


HTTP를 사용하여 데이터를 가져오고 나중에 결과 데이터를 비동기적으로 처리하려고 한다고 가정해 보겠습니다. 아래와 같이 done 블록을 작성할 수 있습니다.

getDataFromHttp()
  .then(function (result) {
    return processDataAsync(result);
  })
  .done(function (processed) {
    displayData(processed);
  });


향후 처리 라이브러리 API가 동기식으로 변경되면 아래와 같이 완료 블록을 제거할 수 있습니다.

getDataFromHttp().then(function (result) {
  return displayData(processDataAsync(result));
});


그런 다음 done 블록을 추가하는 것을 잊고 차단하면 자동 오류가 발생합니다.

3. Bluebird의 ES6 Promise 확장
Bluebird는 ES6 Promises API를 확장하여 두 번째 솔루션의 문제를 방지합니다. 이 라이브러리에는 거부된 Promise에서 stderr로 모든 오류를 인쇄하는 "기본"onRejection 핸들러가 있습니다. 설치 후 처리되지 않은 거부를 처리할 수 있습니다.

Promise.onPossiblyUnhandledRejection(function (error) {
  throw error;
});


거부를 버리고 빈 캐치로 처리하십시오.

Promise.reject("error value").catch(function () {});


JavaScript는 예외를 삼키는 것을 약속합니다.



스택 추적이 인쇄되지 않으면 충돌을 디버그하기가 매우 어렵습니다. 수동으로 오류를 찾으려는 경우가 됩니다.

GET /foo/bar/
Doing something useful
Error: Expected } near ;


ES6 Promise는 이를 변경할 수 있는 기능을 제공하지 않는 것 같고, Bluebird는 Promise에 .catch() 사례를 추가하지 않은 경우에만 사용할 수 있는 [Possibly]UnhandledRejection이 있습니다. 처리되지 않은 경우가 아니면 거부에 대한 전역 콜백이 없습니다. 이 문제를 해결하려면 콜백을 실행하는 메서드를 재정의해야 합니다. 이것은 약간 해키이며 변경되지 않는 라이브러리에 의존하지만 오류를 삼키는 것보다 낫습니다.

먼저 아직 설치하지 않았다면 Bluebird를 설치합니다.

npm install --save bluebird


다음으로 이것을 내용으로 하는 파일(bluebird.js라고 함)을 어딘가에 만듭니다.

const Promise = require('bluebird')

// Throw errors in promises rather than calling reject()
// Makes debugging A LOT easier
Promise.prototype._rejectCallback_old = Promise.prototype._rejectCallback
Promise.prototype._rejectCallback =
    function(reason, synchronous, ignoreNonErrorWarnings) {
        if (reason.stack) {
            throw reasong
        } else {
            this._rejectCallback_old(reason, synchronous, ignoreNonErrorWarnings)
        }
    }

module.exports = Promise


또는 reason.stack 이 있으면 인쇄할 수 있지만 디버깅하는 동안 전체 충돌을 선호합니다.

좋은 웹페이지 즐겨찾기