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.

Javier Marín
  • 2,166
  • 3
  • 21
  • 40

2 Answers2

28

You have to catch it to prevent the error

modal.promise.then(hideFn, hideFn).catch((res) => {});
John Velasquez
  • 3,421
  • 2
  • 18
  • 23
  • Is not .catch(onRejected) supposed to be the same as calling .then(onFulfilled, onRejected) with the second parameter being the .catch() handler? – Javier Marín Apr 24 '18 at 09:20
  • 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. – John Velasquez Apr 24 '18 at 09:28
  • 1
    There is not exception thrown, just a call to reject('close') – Javier Marín Apr 24 '18 at 09:30
  • 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 `catch` – John Velasquez Apr 24 '18 at 09:30
  • Doing `modal.promise.finally(() => { debugger; }).catch(() => { debugger; });` shows the same error after the `finally()` callback but before the `catch()` block – Javier Marín Apr 24 '18 at 13:34
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

jiali passion
  • 1,691
  • 1
  • 14
  • 19
  • 3
    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 listener – Javier Marín Apr 24 '18 at 20:09
  • Javier Marín - Thank you. – user3590450 Jan 23 '20 at 04:58
  • Thank you, Javier Martin. I had the same issue. fixed by using .catch() – SUHAIL KC Mar 16 '20 at 11:52
  • @JavierMarín please add `.catch()` as a solution,add proper explanation and accept it as answer,we all facing same issue , Thanks – s4suryapal Jul 11 '20 at 14:56