最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Why would you try-catch around a promise? Does that catch the promise's error? - Stack Overflow

programmeradmin2浏览0评论

I stumbled upon some code that looked off to me:

try {
  somePromise()
    .then(res => console.log(res));
} catch (err) {
  console.error(err);
}

If some somePromise() fails, would this not get caught, and the app would crash? Does this try-catch even do anything?

Should be this, correct?:

  somePromise()
    .then(res => console.log(res))
    .catch(err => console.error(err));

I stumbled upon some code that looked off to me:

try {
  somePromise()
    .then(res => console.log(res));
} catch (err) {
  console.error(err);
}

If some somePromise() fails, would this not get caught, and the app would crash? Does this try-catch even do anything?

Should be this, correct?:

  somePromise()
    .then(res => console.log(res))
    .catch(err => console.error(err));
Share Improve this question edited Apr 30, 2017 at 2:05 atkayla asked Apr 30, 2017 at 2:04 atkaylaatkayla 8,84917 gold badges85 silver badges142 bronze badges 12
  • That does indeed seem wrong. – Chaim Friedman Commented Apr 30, 2017 at 2:05
  • 2 somePromise() could still throw an error. – Felix Kling Commented Apr 30, 2017 at 2:05
  • @FelixKling so the try-catch around it would still crash you're saying because the promise error isn't really handled? – atkayla Commented Apr 30, 2017 at 2:07
  • 2 I'm just saying that inside somePromise an error could be thrown before the promise is returned. – Felix Kling Commented Apr 30, 2017 at 2:08
  • 1 You are right. "undeclared not an exception" is wrong. I mixed up thoughts about es6 and v8/node. Common JS actually catches it as runtime error. – Pinke Helga Commented Apr 30, 2017 at 2:59
 |  Show 7 more comments

2 Answers 2

Reset to default 19

TL;DR - If a function that returns a promise throws an exception before returning the promise then that exception would have to be caught in a regular try-catch block.

Consider this function

function asyncAdd(x,y){
   if(x === 2){
        throw new Error("good old exception")
   }else if(x === 1) { 
      return Promise.reject("fancy exception")
   }

   return Promise.resolve(x+y)
}

This would print "Try caught good old exception"

try{
  asyncAdd(2,10).then(x =>console.log("result", x)).catch(y => console.error("Promise caught", y));
}catch (e){
  console.error("Try caught", e);
}

This would print "Promise caught fancy exception"

try{
  asyncAdd(1,10).then(x =>console.log("result", x)).catch(y => console.error("Promise caught", y));
}catch (e){
  console.error("Try caught", e);
}

If you're dealing with a rubbish function that could return a Promise or throw an Error, that is truly unfortunate. I would recommend a generic tryCatch utility like below to deal with the offensive function.

const badFunction = x =>
{ if (x)
    return Promise.resolve(x)
  else
    throw Error('this is a bad function')
}

const tryCatch = (f, ...args) =>
  new Promise(r => r(f(...args)))

tryCatch(badFunction, 1)
  .then(console.log, console.error)
// 1

tryCatch(badFunction, 0)
  .then(console.log, console.error)
// Error: this is a bad function


Fix it if you can

If the rubbish function is under your control to fix, then I would recommending writing it something like this

const goodFunction = x =>
{ if (x)
    return Promise.resolve(x)
  else
    return Promise.reject(Error('this is a good function'))
}

goodFunction(1).then(console.log, console.error)
// 1

goodFunction(0).then(console.log, console.error)
// Error: this is a good function


Uncaught errors in .then-chained functions

That's not to say that sometimes we still might encounter a situation where you will need to use a function that could throw. For example, if we then a function that can throw – JSON.parse in this case - Promises are already equipped to handle this in a convenient way; the thrown Error will be captured inside of a rejected promise

const goodFunction = x =>
  Promise.resolve(x)
  
goodFunction('"abc"')
  .then(JSON.parse)
  .then(console.log, console.error)
  // 'abc'

goodFunction('abc')
  .then(JSON.parse)
  .then(console.log, console.error)
  // 'Unexpected token a in JSON at position 0'


Uncaught errors in Promise executor

If a function throws an error in your Promise executor, don't worry, the error will be contained in an automatically rejected promise -

const okFunction = x =>
  new Promise(resolve => resolve(JSON.parse(x)))

okFunction('"abc"').then(console.log, console.error)
// 'abc'

okFunction('abc').then(console.log, console.error)
// Error: Unexpected token a in JSON at position 0

发布评论

评论列表(0)

  1. 暂无评论