Rejecting a promise throws "Uncaught (in promise)"
Asked Answered
S

2

12

I'm using promises to handle to handle a modal dialog: resolved when the user press the OK button, rejected when cancelled or closed.

To resolve and dismiss the modal I use this methods:

    let modalResolve, modalReject;
    modal.promise = new Promise<any>((resolve, reject) => {
        modalResolve = resolve;
        modalReject = reject;
    });
    modal.close = (result) => {
        if (modal.isOpen) {
            modalResolve(result);
        }
    };
    modal.dismiss = (reason) => {
        if (modal.isOpen) {
            modalReject(reason);
        }
    };
    modal.promise.finally(() => modalElement.remove());

And when cancel button fires this method within the modal:

modal.dismiss('close')

Everything is working fine and the modal hides, but a console error is logged with this description and stack:

Error: Uncaught (in promise): close
    at resolvePromise (zone.js:814)
    at resolvePromise (zone.js:771)
    at eval (zone.js:873)
    at ZoneDelegate.invokeTask (zone.js:421)
    at Object.onInvokeTask (core.js:4751)
    at ZoneDelegate.invokeTask (zone.js:420)
    at Zone.runTask (zone.js:188)
    at drainMicroTaskQueue (zone.js:595)
    at ZoneTask.invokeTask [as invoke] (zone.js:500)
    at invokeTask (zone.js:1540)

It is weird because the modal is dismissed anyway, and this error is not shown on all modals I use, just in some of them. Resolving does not produce this kind error.

Schapira answered 24/4, 2018 at 8:32 Comment(1)
here's the smallest reproduction of the error: stackblitz.com/edit/zonejs-promise-rejectGinaginder
M
28

You have to catch it to prevent the error

modal.promise.then(hideFn, hideFn).catch((res) => {});
Maledict answered 24/4, 2018 at 8:48 Comment(5)
Is not .catch(onRejected) supposed to be the same as calling .then(onFulfilled, onRejected) with the second parameter being the .catch() handler?Bornite
yes you can do it that way, but base on the error the promise throws an exception that is why we have to call the catch to prevent the exception error.Maledict
There is not exception thrown, just a call to reject('close')Bornite
example would be this way var promise1 = new Promise(function(resolve, reject) { throw 'Uh-oh!'; }); that is why the app crashed because of the throw, to prevent it we have to call catchMaledict
Doing modal.promise.finally(() => { debugger; }).catch(() => { debugger; }); shows the same error after the finally() callback but before the catch() blockBornite
S
1

just like Amaya said, you must use catch to catch the error, otherwise it will become a UnhandledPromiseRejection, different promise vender have different implementations to handle such kind of UnhandledPromiseRejection, but in either way, it will just be thrown at some point, so zone.js will throw the error in the next tick.

And I see you have already used finally, if you use finally UnhandledPromiseRejection should not be thrown, but you need to use zone.js 0.8.26 to support Promise.finally, if the error still exists when you upgrade the zone.js, please tell me or fire an issue in zone.js repository, https://github.com/angular/zone.js/issues

Spelter answered 24/4, 2018 at 17:56 Comment(4)
Thank you, I found that the cause of my error was that I was using .then() in other places of my code, without a .catch(). I thought that with one catch for each promise was enough, but it seems it has to be set for each listenerBornite
Javier Marín - Thank you.Welles
Thank you, Javier Martin. I had the same issue. fixed by using .catch()Earlie
@JavierMarín please add .catch() as a solution,add proper explanation and accept it as answer,we all facing same issue , ThanksBridie

© 2022 - 2024 — McMap. All rights reserved.