development

Promise에서 잡히지 않은 예외를 잡는 방법

big-blog 2020. 11. 12. 19:00
반응형

Promise에서 잡히지 않은 예외를 잡는 방법


Promise 예외를 포함하여 모든 예외를 전역 적으로 catch하는 방법이 있습니까? 예:

    window.onerror = function myErrorHandler(errorMsg, url, lineNumber) {
        alert("Error occured: " + errorMsg);//or any message
        return false;
    }

    var myClass = function(){

    }


    var pr = new Promise(function(resolve, react){
        var myInstance = new myClass();
        myInstance.undefinedFunction(); // this will throw Exception
        resolve(myInstance);
    });


    pr.then(function(result){
        console.log(result);
    });

    // i know right will be this:
    // pr.then(function(result){
    //     console.log(result);
    // }).catch(function(e){
    //     console.log(e);
    // });

이 스크립트는 오류없이 자동으로 종료됩니다. 방화범에는 아무것도 없습니다.

제 질문은 제가 실수를해서 잡는 것을 잊었다면 전 세계적으로 잡을 수있는 방법이 있습니까?


업데이트, 기본 약속은 이제 대부분의 브라우저에서 다음을 수행합니다.

window.addEventListener("unhandledrejection", function(promiseRejectionEvent) { 
    // handle error here, for example log   
});

우리는 요 전에 이것에 대해 논의하고있었습니다.

블루 버드로이 작업을 수행하는 방법은 다음과 같습니다.

window.onpossiblyunhandledexception = function(){
    window.onerror.apply(this, arguments); // call
}

window.onerror = function(err){
    console.log(err); // logs all errors
}

Bluebird를 사용하면 Promise.onPossiblyUnhandledRejection. done라이브러리가 Q와 달리 처리되지 않은 거부 자체를 감지하므로 호출 이 필요하지 않습니다 (UPDATE 2016-이제 Q에 대한 코드를 작성했으며이를 수행합니다).

As for native promises - they will eventually report to either window.onerror or a new handler but the specification process is not yet done - you can follow it here.


Most promise implementations don't currently provide the type of functionality you are referring to, but a number of 3rd-party promise libraries (including Q and bluebird) provide a done() method that will catch and rethrow any uncaught errors, thus outputting them to the console.

(Edit: see Benjamin Gruenbaum's answer about Bluebird's features for handling uncaught exceptions)

So if you have that, you'd just need to follow the rule of thumb that any promise you use should either be returned or terminated with .done():

pr.then(function(result){
    console.log(result);
})
.done();

To quote from the Q API reference:

The Golden Rule of done vs. then usage is: either return your promise to someone else, or if the chain ends with you, call done to terminate it. Terminating with catch is not sufficient because the catch handler may itself throw an error.

I realize that this still requires a bit of extra work and you can still forget to do this, but it is an improvement over having to .catch() and explicitly handle every error, especially for the reason pointed out above.


In Node.js, you can use:

process.on('unhandledRejection', (reason, promise) => {
  console.error(`Uncaught error in`, promise);
});

If you're writing code that can be executed both in a browser & in a Node.js environment, you could wrap your code in a self-executing function like this :

var isNode = (typeof process !== 'undefined' && typeof process.on !== 'undefined');
(function(on, unhandledRejection) {
    // PUT ANY CODE HERE
    on(unhandledRejection, function(error, promise) {
        console.error(`Uncaught error in`, promise);
    });
    // PUT ANY CODE HERE
})(
    isNode ? process.on.bind(process) : window.addEventListener.bind(window),
    isNode ? "unhandledRejection" : "unhandledrejection"
);

What would happen if you use this code :

  • If you'd run it in a Node.js environment, your handler would be attached to the process object and be executed when you have an uncaught exception in a promise.

  • If you'd run it in a browser environment, your handler would be attached to the window object and be executed when you have an uncaught exception in a promise and your browser supports the unhandledrejection event.

  • If you'd run it in a browser environment without support for the unhandledrejection, you will not be able to catch your uncaught exception and your unhandledrejection event handler will never be triggered, but you would not get any errors if there's no uncaught exceptions.


If you are using native Promise, it's pretty simple.
You only need to .catch this reject some where.

ajax(request).catch(function(rejected){
      console.log(rejected);
});

If I don't catch it somewhere, the uncaught in promise will keep showing. But If I catch it somewhere...

참고URL : https://stackoverflow.com/questions/28001722/how-to-catch-uncaught-exception-in-promise

반응형