如何捕获异步非承诺错误? (对该特定错误做出反应)

How can I catch asynchronous-non-promised errors ? ( react to that specific error)

我知道那里有答案,但我没有找到我实际问题的具体答案。

目前我use以下模式很多:

 class A
 {
     getLocation()
     {
         return Promise.reject(2222222)
     }
     async a()
     {
         try
         {
             var loc = await this.getLocation();
             alert(loc)
         }
         catch (e)
         {
             alert("catch 2")
         }
     }
 }
 new A().a();
  • Result : "catch 2"

事件如果我在 getLocation 中抛出错误:

  getLocation()
     {
         throw Error("ffffff")
     }

- 我得到相同的结果 - 没关系。

那么问题出在哪里呢?

正如您所知,抛出的错误 asynchronously-non-promised 是另一种野兽:

所以根本this code won't be catched

  getLocation() //bad code from a third party code , third party code
  { 
      return new Promise((v, x) => setTimeout(() =>
      {
          throw Error("ffffff")
      }, 100))
  }

问题:

关于我想捕获错误这一事实 - 是否有更好的捕获错误的模式?

我当然可以:

window.onerror = function () { alert(4)}

但这与 .catch(...)catch(){} 的流程不符,我将无法对 that 执行操作导致错误的具体操作。

完全披露:
没有真实的生活场景。学习目的.

应该在错误发生的地方捕获错误。

这种代码代码不正确,应该原地修复:

  getLocation() //bad code from a third party code
  { 
      return new Promise((v, x) => setTimeout(() =>
      {
          throw Error("ffffff")
      }, 100))
  }

如果这是第三方代码,可以对其进行分叉或修补。

onerror 可以全局跟踪异常,正如问题中已经提到的那样。这应该只用于通知开发人员存在的错误,而不是以正常方式处理它们。

unhandledrejection 事件可用于相同目的,以通知未处理的承诺拒绝。它将无法处理上面片段中的错误,因为它被抛入 setTimeout 回调中并且不会导致 promise 被拒绝。

我猜基本用法是这样的:

class A {
  getLocation(x) {
    return new Promise((resolve, reject) => setTimeout(() => {
      // a lot of async code
      try {
        //simulate unexpected exception    
        if (x === 2) {
          throw ("code error");
        }
        if (x) {
          resolve('success');
        } else {
          reject('conditional rejection');
        }
      } catch (ex) {
        reject(ex);
      }
    }, 1000));
  }
  async a(x) {
    await this.getLocation(x).then((loc) => console.info(loc)).catch((e) => console.error(e));
  }
}
let o = new A();
o.a(2);
o.a(0);
o.a(1);

Promise 的拒绝不一定是代码 Exception,代码 Exception 也不一定会触发 Promise 拒绝。

an error which is thrown asynchronously-non-promised is a different beast

是的。必须不惜一切代价避免它。因此,从不 将业务代码(包括 属性 访问等琐碎的事情)放在异步非承诺回调中。它可以扔!很明显,JSON.parse 可能会失败,当 "object" 是 nullundefined 或 getter 时,属性 访问会抛出异常涉及,或者当应该是数组的东西没有 .length.

时,循环可能会失败

唯一允许作为异步非承诺回调的是 resolvereject(err, res) => { if (err) reject(err); else resolve(res); }(对于具有多个参数的奇怪 API 可能是可变参数版本)。

所以将错误代码重写为

async getLocation() {
    await new Promise(resolve => setTimeout(resolve, 100));
    throw Error("ffffff");
}

getLocation() {
    return new Promise(resolve => setTimeout(resolve, 100)).then(res => {
        throw Error("ffffff");
    });
}

当它是第三方代码时,让他们修复它,对你的修复提出上游合并请求,或者如果这些不起作用,则放弃该方。

is there a better pattern for capturing this?

好吧,domains (in node) were supposed to solve this problem of non-locality of asynchronous (uncaught) exceptions, but they didn't work out. Maybe some day, zones 具有更好的母语支持将取代它们。