0

EDIT: Please see Edit-Start below,

I am receiving this error when I try to reject a promise: -

"VM168:3 Uncaught (in promise) I love You !!"

If you look at the example below you'll see that the THEN caters for both Resolve and Reject outcomes. If you remove the comment markers /* */ and run it again you'll see there is no error generated.

Why is this error occuring?

Example credit to w3schools: -

<!DOCTYPE html>
<html>
<body>
<h2>JavaScript Promise</h2>

<p>Wait 3 seconds (3000 milliseconds) for this page to change.</p>

<h1 id="demo"></h1>

<script>
const myPromise = new Promise(function(myResolve, myReject) {
  setTimeout(function(){ myReject("I love You !!"); }, 3000);
});
/*
myPromise.then(function(value) {
  document.getElementById("demo").innerHTML = value;
},
function(value) {
  document.getElementById("demo").innerHTML = "Boom"+value;
});*/
</script>
<input typt="text"/>
</body>
</html>

Edit-Start

So the "Uncaught (in promise)" appears in the console as an Error and NOT a Warning yet all following instructions (post calling myReject) are executed. Probably as, IIRC, promises are held over to the next event loop by design.

So even if I try (see what I did there :-) to trap the error, I can't!

const myPromise = new Promise(function(myResolve, myReject) {
  setTimeout(
    function(){ try{
                    myReject("I love You !!");
                } catch(err) {
                  console.log("Err = "+err.message) 
                }
              }, 3000);
});

How marvellously consistent and retrospectively compatable :-(

At least the state of myPromise is set to Rejected. Thank heaven for small mercies!

McMurphy
  • 1,235
  • 1
  • 15
  • 39
  • 3
    `Why is this error occuring?` because you have a Promise rejecting, and no code to handle the rejection – Bravo Jul 15 '21 at 01:45
  • 2
    A promise rejection is very similar to a thrown exception, so this is similar to if you did `throw "I love You !!";` with no `try/catch` to handle the exception (and thus would log an error in the console like this). I'd personally consider calling `reject` with any value that isn't `instanceof Error` to be a code smell that would concern me. – loganfsmyth Jul 15 '21 at 01:48
  • The error is always occurring, whether you handle it or not. – Bergi Jul 15 '21 at 02:04
  • Surely the whole point of Promises and aysync coding is that you can wait/then a promise at any time in the futue or not at all? So has the REJECT failed? What is the state of myPromise after the rejection "failure". IMHO Promise longevity and Promise-State longevity should not be limited by immediate scope. In my case, and I'm sure many others, I'm not ready to wait for promise resolution/rejection yet. It is a Rejection/state-change and NOT a Throw. – McMurphy Jul 15 '21 at 03:13
  • Please see my Edit in the main question for more info. – McMurphy Jul 15 '21 at 03:36
  • `myReject` is just a regular function just like any other functions in javascript. Calling it does not trigger an error. Instead it signals to the Promise object that an error has occured. `try/catch` catches errors. Since calling functions is not an error it would not catch you calling `myReject`. Remember: promises is not a language feature of javascript. It is just a design pattern that has been implemented as a library (and included in javascript's standard library) – slebetman Jul 15 '21 at 04:18
  • 1
    Is your question here is about the _timing_ of the logging, because something could come along later and do `myPromise.catch(err => {})` and thus it actually is possible the error could be handled eventually? If so, that's very unclear. – loganfsmyth Jul 15 '21 at 05:27
  • @McMurphy "*What is the state of myPromise after the rejection "failure"?" - it's rejected, and has no rejection handlers attached to it. That gives you a stern warning that something is wrong with your code. "*In my case, and I'm sure many others, I'm not ready to wait for promise resolution/rejection yet*" - no, that's not a common case, far from normal actually. Why are you ready to start a timeout that can fail, but are not ready to handle the result of the asynchronous action? Please tell us more about your actual use case. – Bergi Jul 15 '21 at 23:20

1 Answers1

0

For those of you who understand the obvious requirement and don't want your cosnsole messed up with spurious errors, put this rubbish after you instantiate your Promise before exiting scope (yeild the event thread): -

myPromise.then(()=>{},()=>{console.log("disbelief")});

Async functions notwithstanding!

Complete Example: -

<!DOCTYPE html>
<html>
<body>
<h2>JavaScript Promise</h2>

<p>Wait 3 seconds (3000 milliseconds) for this page to change.</p>

<h1 id="demo"></h1>

<script>
const myPromise = new Promise(function(myResolve, myReject) {
  setTimeout(
    function(){ try{
                    myReject("I love You !!");
                } catch(err) {
                  console.log("Err = "+err.message) 
                }
                setTimeout(stillThere,0);
              }, 3000);
});
myPromise.then(()=>{},()=>{console.log("disbelief")});
function stillThere() {
  console.log("start");
  myPromise.then(function(value) {
    document.getElementById("demo").innerHTML = value;
  },
  function(value) {
    document.getElementById("demo").innerHTML = "Boom"+value;
  });
  console.log("end");
}

</script>
<input typt="text"/>
</body>
</html>
McMurphy
  • 1,235
  • 1
  • 15
  • 39
  • Try not to use the second argument of `.then()`. If possible prefer using `.catch()`. So always handle your promises like this: `mypromise.then(handleIt).catch(console.log)` – slebetman Jul 15 '21 at 04:20
  • 1
    Also, `disbelief` is not a useful error message and you will kick yourself debugging your code looking at the console with lots of `disbelief`. Just pass `console.log` to the `.catch()` method of your promise. – slebetman Jul 15 '21 at 04:21
  • @slebetman There is [absolutely nothing wrong with using the second argument to `then`](https://stackoverflow.com/q/24662289/1048572) where it makes sense. Sure, passing nothing as the the first argument means you should simplify to `.catch(…)`. – Bergi Jul 15 '21 at 23:22
  • @Bergi I find it less readable because you don't immediately see the intent of the code. With `.catch()` it tells you it's catching errors. – slebetman Jul 16 '21 at 03:00