javascript - React 全局错误处理程序不适用于异步 componentDidMount。尝试了 componentDidCatch 和 window.onerror
问题描述
我有以下代码index.tsx
:
window.onerror = function(msg, url, line, col, error) {
debugger;
// Note that col & error are new to the HTML 5 spec and may not be
// supported in every browser. It worked for me in Chrome.
var extra = !col ? '' : '\ncolumn: ' + col;
extra += !error ? '' : '\nerror: ' + error;
// You can view the information in an alert to see things working like this:
alert("Error: " + msg + "\nurl: " + url + "\nline: " + line + extra);
// TODO: Report this error via ajax so you can keep track
// of what pages have JS issues
var suppressErrorAlert = true;
// If you return true, then error alerts (like in older versions of
// Internet Explorer) will be suppressed.
return suppressErrorAlert;
};
资源:
https://stackoverflow.com/a/10556743/3850405
如果我在另一个组件中抛出这样的错误,我将按预期捕获它:
componentDidMount() {
throw new Error();
}
如果这样抛出:
async componentDidMount() {
throw new Error();
}
错误未被捕获并Unhandled Rejection (Error):
显示。
然后我尝试创建一个 React 全局错误边界。
import React, { ErrorInfo } from 'react';
interface IProps {
}
interface IState {
hasError: boolean
}
class ErrorBoundary extends React.PureComponent<IProps, IState> {
constructor(props: IProps) {
super(props);
this.state = { hasError: false };
}
componentDidCatch(error: Error, info: ErrorInfo) {
// Display fallback UI
debugger;
console.warn(error);
console.warn(info);
this.setState({ hasError: true });
// You can also log the error to an error reporting service
//logErrorToMyService(error, info);
}
render() {
if (this.state.hasError) {
// You can render any custom fallback UI
return <h1>Something went wrong.</h1>;
}
return this.props.children;
}
}
export default ErrorBoundary
索引.tsx:
<React.StrictMode>
<Provider store={store}>
<ConnectedIntlProvider>
<Router>
<ErrorBoundary>
<App />
</ErrorBoundary>
</Router>
</ConnectedIntlProvider>
</Provider>
</React.StrictMode>,
资料来源:
https://reactjs.org/blog/2017/07/26/error-handling-in-react-16.html
https://stackoverflow.com/a/51764435/3850405
然而效果是一样的,async componentDidMount
没有被捕捉到,但除此之外它按预期工作。
我发现这个线程提到了这个问题,但没有真正的解决方案。
https://stackoverflow.com/a/56800470/3850405
如何在 React 中创建一个真正捕获所有内容的全局错误处理程序?
解决方案
在与@Pointy 讨论后,我决定这样解决:
window.onerror = (msg, url, line, col, error) => {
// Note that col & error are new to the HTML 5 spec and may not be
// supported in every browser. It worked for me in Chrome.
var extra = !col ? '' : '\ncolumn: ' + col;
extra += !error ? '' : '\nerror: ' + error;
// You can view the information in an alert to see things working like this:
console.error("Error: " + msg + "\nurl: " + url + "\nline: " + line + extra);
// TODO: Report this error via ajax so you can keep track
// of what pages have JS issues
var suppressErrorAlert = true;
// If you return true, then error alerts (like in older versions of
// Internet Explorer) will be suppressed.
return suppressErrorAlert;
};
window.onunhandledrejection = (e: PromiseRejectionEvent) => {
console.error(e);
throw new Error(e.reason.stack);
}
资源:
推荐阅读
- javascript - 似乎无法在反应中从此 api 中检索数据
- c++ - 使用 Intel Performance Primitives FFT 函数 ippsConjPack_64fc,为什么输出大小与输入大小相同?
- python - 在 pyglet/opengl 中渲染纹理立方体的最有效方法
- delphi - Delphi 10.3 函数 CharUpper 和 CharUpperW 不同 Delphi 10.4
- bazel - 如何离线使用 Bazel 构建
- bash - 如何让 bash 制表符完成以在参数开始时停止转义 glob 通配符?
- rust - 在循环中变异时,可变借用时间过长
- c# - 无法从 UI 线程更新富文本框..?
- assembly - System V ABI - AMD64 - GCC 发射程序集中的堆栈对齐
- swift - 使用 AVAudioEngine 增强语音记录,例如 Voice Memos