Search code examples
javascriptpromisesettimeout

Catching an exception from the setTimeout function executed inside an instance of a Promise object


Dear participants please tell me the solution.

In this block of code, the catсh method perfectly catches the exception:

const myPromise = new Promise(() => {
  throw new Error(`Oops! Threw an exception`);
});

// We catch the exception in the method `catch`.
myPromise
  .catch((error) => console.log(error.message));

And in this block, the catсh method will not be called:

сonst TIMEOUT = 1000;

const mySecondPromise = new Promise((resolve, reject) => {
  setTimeout(() => {
    throw new Error(`Error in asynchronous function`);
  },
  TIMEOUT
  );
});

mySecondPromise
  .catch(() => console.log(`This code will not be executed`));

Please explain:

  1. Why is this happening (I suppose this is due to Event Loop)?
  2. How to rewrite the code so that catching an exception in the catch method works with setTimeout?

Thank you all for the answers!

Here is a life example:

import moment from "moment";

const Delay = (timeout, timePress) => {
    return new Promise((res => setTimeout(() => {
            res(`${moment().format("LTS")} ${timeout} ${timePress}`);
        }, timeout * 1000)
    ));
};

export default Delay;

I want, If for some reason an exception is thrown in the setTimeout function, I should be able to catch it. Like this:

Delay.catch(() => console.log(`This code will not be executed`));

Solution

  • After some discussions and comments, my task was solved by this approach:

    const someFunction = timeout => new Promise(resolve => setTimeout(resolve, timeout));
    
    someFunction(timeout).then(() => doSomething()).catch(() => console.log(`This code will not be executed`));
    

    If an exception occurs in an asynchronous function:

    someFunction(timeout).then(ErrorEvent).catch(() => console.log(`This code will not be executed`));
    

    Such solutions are still possible:

    const testF = () => { throw new Error(`Упс! Бросили исключение.`) }
    
    const genPromise = () => new Promise((resolve, reject) => {
        setTimeout(() => {
            try {
                const res = testF()
                resolve(res)
            } catch (e) { reject(e) }
        }, 1e3)
    })
    
    t1: {
        const log = console.log.bind(console, 't1:')
        const _then = log.bind(console, 'then:')
        const _catch = log.bind(console, 'catch:')
    
        genPromise()
            .then(_then)
            .catch(_catch)
            .then(_then)
    }
    
    t2: {
        const log = console.log.bind(console, 't2:')
        const _then = log.bind(console, 'then:')
        const _catch = log.bind(console, 'catch:')
    
        void async function () {
            let pRes = null
            try {
                pRes = await genPromise()
            } catch (e) {
                _catch(e.message)
            }
            _then(pRes)
        }()
    }