Stanley
Stanley

Reputation: 2806

Handling Js promise rejection

How do you handle an error (eg. "new error" below) that is outside of the promise?

function testError() {
    throw new Error("new error") // how to handle this?
    var p123 = new Promise(function(resolve, reject) {
         resolve(123)
    });
    return p123
};

testError().catch(err => {
        return err;  // code doesn't come here
    })
    .then(ok => {
        console.log(ok)
    });

Upvotes: 5

Views: 19051

Answers (5)

jib
jib

Reputation: 42430

You rewrite it, because making a caller check for both exceptions and rejections is an anti-pattern:

function testError() {
  return Promise.resolve().then(() => {
    throw new Error("new error"); // rejects returned promise
    return new Promise(function(resolve) {
      resolve(123);
    });
  });
}

testError().catch(err => console.log("Caught " + err));

This is implicit with async functions; they always return a promise:

async function testError() {
  throw new Error("new error"); // rejects implicit promise
  return await new Promise(function(resolve) {
    resolve(123);
  });
}

testError().catch(err => console.log("Caught " + err));

Upvotes: 0

Mulan
Mulan

Reputation: 135187

If you can, rewrite your testError function like so

function testError () {
  return new Promise(function (resolve, reject) {
     throw new Error('new error')
     resolve(123)
  })
}

testError().then(ok => console.log(ok),
                 err => console.error(err.message))

  1. Run it once to see it throw the error in console.error
  2. Comment out the throw line to see the promise resolve successfully

Upvotes: 1

Wiktor Zychla
Wiktor Zychla

Reputation: 48230

Since the error doesn't involve the async code, a regular try-catch should do fine here:

try {
  testError().catch(err => {
    return err;  // code doesn't come here
  })
  .then(ok => {
     console.log(ok)
  });
}
catch(e) {
   // 
}

Note that when the async-await pattern finally becomes the native way of resolving promises, the try-catch will also become the native way of handling errors:

try {
    var ok = await testError();
    console.log(ok)
}
catch(e) {
    console.log('e:' +e);
}

As one can easily verify, this one correctly handles both the sync and the async error and is much cleaner than then-catch.

Upvotes: 4

clinton3141
clinton3141

Reputation: 4841

Since the error is thrown outside of the promises, you cannot catch it using a promise catch statement.

You can use a try/catch to catch the error instead.

function testError() {
    throw new Error("new error") // how to handle this?
    var p123 = new Promise(function(resolve, reject) {
         resolve(123)
    });
    return p123
};

try {
  testError().then(ok => {
    console.log(ok)
  });
} catch (err) {
  console.log(err.message);
}

Upvotes: 0

JLRishe
JLRishe

Reputation: 101652

If you're not sure whether a function will throw (or return a value) synchronously, you can call it using .then(). This will wrap it so that the result will be handled consistently no matter how it is produced:

function testError() {
  throw new Error("new error") // how to handle this?
  var p123 = new Promise(function(resolve, reject) {
    resolve(123)
  });
  return p123
};

Promise.resolve()
  .then(testError)
  .catch(err => {
    console.error(err);
    return err; 
  })
  .then(ok => {
    console.log(ok.message)
  });

Upvotes: 6

Related Questions