Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handle error from setTimeout

Simple question about try/catch for function in setTimeout

try {
    setTimeout(function () {
        throw new Error('error!');
    }, 300)
} catch (e) {
    console.log('eeee!')
    console.log(e)
}

Why doesn't catch block work?

What can I read about this?

P.S: the question is about possibility of handling errors like this. Don't answer about promises.

like image 830
Andrew Kochnev Avatar asked Jan 02 '17 18:01

Andrew Kochnev


People also ask

How do I get setTimeout error?

You have to wrap the inside of the callback, since setTimeout(() => {throw new Error();}, 1000); is a successful call. The error doesn't come until later.

How does node js handle timeout exception?

I noticed that in the timeout event both the 'abort' event is triggered and the request callback is called, in this order, so I used the setTimeout function to wait for the request callback and than handle the error in the 'abort' listener.

Does setTimeout block code?

Explanation: setTimeout() is non-blocking which means it will run when the statements outside of it have executed and then after one second it will execute.

Does setTimeout stop execution?

No, setTimeout does not pause execution of other code.


3 Answers

Functions scheduled to run with setTimeout are executed in the main loop, outside the body of code that originated them.

To handle errors, put the try-catch inside the setTimeout handler:

setTimeout(function () {
  try {
    throw new Error('error!');
  } catch (e) {
    console.error(e);
  }
}, 300)

If you need to access the Error object from block that called setTimeout, use Promises:

const promise = new Promise((resolve, reject) => {
  setTimeout(function () {
    try {
      throw new Error('error!');
      resolve(); // if the previous line didn't always throw

    } catch (e) {
      reject(e)
    }
  }, 300)
})

promise
  .then(result => console.log("Ok " + result))
  .catch(error => console.error("Ouch " + error))

This example above is not the most elegant way of handling the case with a Promise. Instead, implement a delay(ms) function like this:

function delay(ms) {
  return new Promise(resolve => setTimeout(resolve, ms))
}

Then call

delay(300).then(myFunction).catch(handleError)
like image 87
slezica Avatar answered Oct 26 '22 23:10

slezica


You can find good explanation in this Node.js official doc.

The problem is that when the callback of your setTimeout() function executes the try { } catch(err) { } block is already exited. Also notice that the callback can crash Node.js process.

However if you want to handle the errors in the callback of setTimeout() function, then you can listen them by using process global EventEmitter object

process.on('uncaughtException', function(err){
  console.log(err)   
})
like image 31
Karlen Avatar answered Oct 26 '22 21:10

Karlen


Because the catch block lexically surrounds the setTimeout call but that is not the function that throws. The direct translation, is

setTimeout(function () {
  try {
    throw new Error('error!');
  } catch (e) {
    console.log('eeee!');
    console.log(e);
  }
}, 300);
like image 3
Aluan Haddad Avatar answered Oct 26 '22 23:10

Aluan Haddad