0

While working on asynchronous functions in JavaScript. I discovered this problem.

A function needs to perform some asynchronous task, however that task doesn't make difference to function result. So function return its result, and after a while an exception is thrown from asynchronous function, however since control is already returned so exception goes unhanded.

Note: Not to change notify I'm intentionally throwing error like that, need to only handle this exception

Code is like:

function notify() {   //To send notification
    setTimeout( function() {   //Just to simulate an asynchronous function
        throw "Exception occurred";   //An exception from async function
    },2000);

    return "Notified";
}

try {
    let result = notify();
    console.log(result);    //Notified
}
catch (error) {   //Never comes to catch block.
    console.log(error);
}

How can to catch this exception. Tried using Promise, however it doesn't resolved with promise because even with promise, flow or function is removed from memory as calling function have received response.

Code using Promises

function notify() {   //To send notification

    return new Promise ( (resolve, reject) => {
        setTimeout( function() {   //Just to simulate an asynchronous function
            throw "Exception occurred";   //An exception from async function
        },2000);

        resolve("Notified");
    });
}

notify()
.then( result => {
    console.log(result);    //Notified
})
.catch( error => {   //Never comes to catch block
    console.log(error);
});

How can I catch exception in JavaScript programming?

NAVIN
  • 3,193
  • 4
  • 19
  • 32
  • I would first reevaluate your initial claim that the "task doesn't make difference to function result". If an exception occurs when trying to send the notification, then clearly the result of knowing whether it was successful or not depends on that asynchronous task. – Patrick Roberts Aug 19 '18 at 19:33
  • I think [this post](https://stackoverflow.com/a/32385430/1048572) should answer your question – Bergi Aug 19 '18 at 19:53
  • `notify` should not immediately `resolve()`. It should call `reject()` instead of `throw`ing the exception. – Bergi Aug 19 '18 at 19:54

2 Answers2

2

I would wrap setTimeout in a promise as:

  const delay = ms => new Promise(res => setTimeout(res, ms));

That allows you to write notify as:

  async function notify() {
    await delay(2000);
    throw new Error();
  }

  notify().then(/*...*/).catch(/*...*/);

The trick here is that throw is inside of an asynchronous function and not as in your case inside of a callback.

Jonas Wilms
  • 132,000
  • 20
  • 149
  • 151
  • Yes, this fixes the OPs code that `throw`s inside of the `setTimeout` callback, but doesn't hold "*So the function returns its result, and after a while an exception is thrown*" any more – Bergi Aug 19 '18 at 20:59
  • @bergi `notify().catch(...); getResult().then(...)` ... but thats hard to tell from OPs code. – Jonas Wilms Aug 20 '18 at 05:22
  • My question is different. You are asking me to wait for that Asynchronous function to return or finish its execution. I don't want to wait for its execution. However if that asynchronous function throw an error my application is terminated. – NAVIN Aug 21 '18 at 07:32
  • 1
    @navin then use Promise.race – Jonas Wilms Aug 21 '18 at 12:57
1
    var notify = function () {
        anOddTask();
        return "Notified";
    }


    async function anOddTask() {
        try {
            await setTimeout( function() {  
            },2000);
            throw new Error("Exception occurred");
        }
        catch (err) {   
            console.log(err);
        }
    }

    try {
        let result = notify();
        console.log(result);    //Notified
    }
    catch (error) {   //Never comes to catch block.
        console.log(error);
    }

This will immediately return "Notify" and handle the rejection at some later time. If you wish that "Notify" be returned as a resolved promise than just make notify() an async function.

    var notify = async function () {
        anOddTask();
        return "Notified";
    }
Unheilig
  • 16,196
  • 193
  • 68
  • 98
Fred
  • 152
  • 5