Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Uncaught (in promise) Error

This is obviously a SSCCE. I have the following (jsFiddle here):

<html>
  <body>
    <input id='file-dlg' type='file'/>
    <br/>
    <button id='submit' type='button'>submit</button>
    <script>
     document.getElementById('file-dlg').addEventListener('change', storeAPromise);
     var p; 
     function storeAPromise() {
       p = new Promise(function executor(resolve, reject) {
         try {
           throw new Error('snafu');
         } catch(e) {
           reject(e);
         }
       });
     };
     document.getElementById('submit').onclick = function() {
       p.then(function() {}, function reject(e) {
         console.error('some problem happenned', e);
       });
     };
    </script>
  </body>
</html>

When the user is using the file dialog to select a file, I expect nothing at all to be printed on the console as the Error is caught and the promise's reject function is called. In contrast, I am expecting the error to appear on the console with the description "some error happened" only when I click the "submit" button.

Yet, this is not what I observe. As soon as the user selects a file with the dialog I see on the console:

Uncaught (in promise) Error: snafu(…)

When the user presses the "submit" button I do see the expected log line "some problem happened" but I don't understand why I also see the earlier "Uncaught (in promise)" log line when the user selects a file with the file dialog. I also don't see why the error is described as "Uncaught" given that I catch (unconditionally) all exceptions and simple invoke the reject function.

like image 504
Marcus Junius Brutus Avatar asked May 22 '18 18:05

Marcus Junius Brutus


People also ask

What is uncaught Promise error?

What does that log "Uncaught (in promise)" mean? It means that there was an error in one of our promises, but we did not write any code in order to handle that error and try to catch it.

How do you catch an error in a Promise?

catch " around the executor automatically catches the error and turns it into rejected promise. This happens not only in the executor function, but in its handlers as well. If we throw inside a . then handler, that means a rejected promise, so the control jumps to the nearest error handler.

How do you handle errors in Promise allSettled?

allSettled() always resolves, even if some promises passed to it reject. It resolves with an array of outcomes for each promise. You can use Promise. all() instead, which will resolve when all passed promises resolve or reject when any passed promise rejects.

How do you handle a Promise rejection?

If an error condition arises inside a promise, you “reject” the promise by calling the reject() function with an error. To handle a promise rejection, you pass a callback to the catch() function. This is a simple example, so catching the rejection is trivial.


1 Answers

It's not an uncaught exception, it's an uncaught rejection. Promises should not be left dangling in the rejected state with no error callback attached - that's why the console is warning you about this. You can also handle these cases in your application with the unhandledrejection event.

If you want to handle the error later (install the handler when the user clicks the button, which might be never!), you still will need to immediately install an empty callback (that explicitly ignores the error) to suppress the warning.

var p = Promise.resolve();
document.getElementById('file-dlg').addEventListener('change', function createPromise() {
  p = new Promise(function executor(resolve, reject) {
    throw new Error('snafu');
  });
  p.catch(e => {/* ignore for now */});
});
document.getElementById('submit').addEventListener('click', function addErrorHandler() {
  p.catch(function onReject(e) {
    console.error('some problem happened', e);
  });
});

Notice that you don't need that try/catch - the promise constructor will catch all exceptions from the executor by default already.

like image 150
Bergi Avatar answered Oct 05 '22 08:10

Bergi