Javascript React全局错误处理程序不适用于异步componentDidMount。已尝试组件didcatch和window.onerror
我在Javascript React全局错误处理程序不适用于异步componentDidMount。已尝试组件didcatch和window.onerror,javascript,reactjs,typescript,Javascript,Reactjs,Typescript,我在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 ? ''
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;
};
资料来源:
如果我在另一个组件中抛出这样的错误,我将按预期捕获它:
componentDidMount() {
throw new Error();
}
如果像这样抛出:
async componentDidMount() {
throw new Error();
}
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);
}
错误未被捕获,并显示未处理的拒绝(错误):
然后我尝试创建一个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
import React,{ErrorInfo}来自“React”;
接口IProps{
}
界面状态{
hasError:布尔值
}
类ErrorBoundary扩展了React.PureComponent{
建造师(道具:IProps){
超级(道具);
this.state={hasError:false};
}
componentDidCatch(错误:错误,信息:错误信息){
//显示回退用户界面
调试器;
控制台。警告(错误);
控制台。警告(信息);
this.setState({hasError:true});
//您还可以将错误记录到错误报告服务
//logErrorToMyService(错误,信息);
}
render(){
if(this.state.hasError){
//您可以呈现任何自定义回退UI
返回出了问题的地方。;
}
返回此.props.children;
}
}
导出默认错误边界
index.tsx:
<React.StrictMode>
<Provider store={store}>
<ConnectedIntlProvider>
<Router>
<ErrorBoundary>
<App />
</ErrorBoundary>
</Router>
</ConnectedIntlProvider>
</Provider>
</React.StrictMode>,
然而,效果是一样的,异步组件didmount
没有被捕获,但在其他方面它工作正常
我发现这个帖子提到了这个问题,但没有真正的解决办法
如何在React中创建一个真正捕获所有内容的全局错误处理程序?与@Pointy讨论后,我决定这样解决它:
async componentDidMount() {
throw new Error();
}
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);
}
资料来源:
@Pointy是的,但我更喜欢像error boundary这样的React方式,但对于未处理的拒绝,那么,async
和Promise实现都是本机JavaScript,React无法对其进行太多控制。@Pointy是的,但错误也是本机的,React确实会处理它们,如上所示。是的,但是承诺链中的错误是通过承诺机制来处理的,因为有关于如何工作的健壮行为保证——完全独立于React。这些“未处理的拒绝”事件直接在内部发布到全局上下文(窗口
或工作全局范围)。