javascript React Native中的全局未处理的promise拒绝处理程序

mqxuamgl  于 2023-08-02  发布在  Java
关注(0)|答案(3)|浏览(129)

我们正在开发react native应用程序,并将firebase与crashlytics一起使用,因此我们可以了解应用程序的折痕和所有未处理的错误。
然而,我们也希望在我们的应用程序中了解所有未处理的promise拒绝-因此我们希望添加全局处理程序/侦听器,以便在这种情况下将信息发送到我们的服务器。
我们已经在一些重要的情况下在各自的.catch()块中发送了这样的信息,但是如果我们将来添加新的promise并且忘记处理它们怎么办-那么我们希望接收信息而不是不知道我们应用中的潜在bug。
或者这是一种不好的做法?

b5lpy0ml

b5lpy0ml1#

要全局跟踪未处理的promise拒绝,可以使用我的react-native-promise-rejection-utils包:

import {
  getUnhandledPromiseRejectionTracker,
  setUnhandledPromiseRejectionTracker,
} from 'react-native-promise-rejection-utils'

const prevTracker = getUnhandledPromiseRejectionTracker()

setUnhandledPromiseRejectionTracker((id, error) => {
  console.warn('Unhandled promise rejection!', id, error)

  if (prevTracker !== undefined) {
    prevTracker(id, error)
  }
})

字符串
或者这是一种不好的做法?
总是有可能收到应用的业务逻辑中没有描述的意外错误(例如:由某个第三方库抛出的异常)。全局记录意外错误是一个很好的实践,因为它可以让您知道存在这样的错误。

2hh7jdfx

2hh7jdfx2#

您可以使用componentDidCatch来实现此目的。您可以 Package 顶级布线组件,也可以 Package 可能包含模糊代码的组件。如何最好地处理应用程序崩溃取决于您。

componentDidCatch(error, errorInfo){}`

字符串
第一个方法参数是实际抛出的错误。第二个参数是一个具有componentStack属性的对象,该属性包含组件堆栈跟踪信息。

wz3gfoph

wz3gfoph3#

我最近一直在努力寻找一个未处理的promise rejection,结果发现这是由于我太信任finally(..)的类型而没有提供参数,而实际上react-native使用的promise polyfill需要finally(..)的参数,否则它会抛出Type Error: undefined is not a function
我写了一篇关于如何通过手动更改Promise polyfill库来识别违规代码行的文章,以便在构造Promise时添加堆栈跟踪,并在存在未处理的Promise拒绝时将其打印出来。
你可以在我发布的这期文章的结尾找到这篇文章。祝你好运,让我知道如果它有帮助!

**编辑1:**我刚刚意识到我会因为没有在这里提供答案而受到憎恨,所以我从这里的问题中复制了它,如果上下文不完全适合,我道歉。同样,这个解决方案是针对一个特定的promise polyfill库,但我想同样的想法可以用于其他库,当它被标记为未处理时,你想跟踪原始promise的堆栈跟踪。

识别违规代码行

我尝试了几个不同的StackOverflow答案,试图找到导致我看到的问题的promise的真实的堆栈跟踪。如前所述,打印的堆栈跟踪最终不会导致我编写的任何代码,这使得它是否是我的错误或潜在的其他一些库导致的问题。
在尝试使用bluebird作为suggested here后,我好奇地发现警告消失了。现在我知道这是因为Bluebird promise实现不需要finally参数!
最后,我做了以下操作来识别有问题的代码行(对不起,这不是一个补丁包补丁,因为我们不使用该库)我手动在两个文件中添加了三行代码。
文件1:node_modules/promise/setimmediate/core.js在function Promise(fn) {...函数中添加以下代码行(我是第61行)。

this._stack = (new Error()).stack;

字符串
文件2:node_modules/promise/setimmediate/rejection-tracking.jsenable函数内部,其中调用了setTimeout(对我来说是第47行):

onUnhandled.bind(null, promise._51)


将其改为:

onUnhandled.bind(null, promise._51, promise)


然后在onUnhandled函数中添加第二个参数“promise”和控制台日志,您将看到_stack字段打印出Promise创建的原始位置。

function onUnhandled(id, promise) { // line 60 for me
    console.log("rejection-tracking:61 - onUnhandled", id, promise)


虽然我得到了一个捆绑的堆栈跟踪,但当代码没有缩小时,我仍然能够跟踪它。

**注意:**这不是高性能的,不应该包含在任何生产构建中,因为在每个promise构造函数上调用(new Error()).stack会使速度减慢很多。对于调试来说,这不是问题。

我很想有人告诉我,我如何可以做到这一点,一个替代的方式,因为我觉得这是荒谬的,我必须通过这些步骤。

相关问题