React:使用 React Router 重定向到带有错误消息/堆栈跟踪的错误页面
2021-04-29
13398
在我的应用中,如果组件内部发生任何错误,我需要重定向到顶级错误页面。假设我使用
React-Router
并定义了以下路由,
<Switch>
..
<Route path="/error">
<Error />
</Route>
假设在某些下级组件中出现故障。我得到一个带有
.message
和
.stack
的
error
对象。我需要我的
Error
组件在 Router
<Redirect />
之后显示错误详细信息。
const [error, setError] = useState({});
const someComponentFetch = async () => {
const url = '/myapp/data';
try {
//...
}
catch (error) {
setError(error);
}
}
if (error.message) {
return <Redirect to="/error" />
}
return (..);
Error
组件需要一个
props
对象:
export default function Error(props) {
return (
<div>
Error Occurred:
<div>
Message: {props.error.message} <br/>
Stack: {props.error.stack}
</div>
</div>
);
}
错误:TypeError:props.error 未定义。
因此
<Redirect>
不会传递我的属性。拥有包含错误详细信息的顶级错误页面的最佳方法是什么?如果我在每个组件中检查
error ? ..
,它就不会是顶级页面,而是每个组件内的一条消息。
2个回答
您可以像这样定义自己的表示,
import React from 'react'
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false, error: '', info: '', stack: '' }
}
static getDerivedStateFromError(error) {
// Update state so the next render will show the fallback UI.
return { hasError: true };
}
componentDidCatch(error, errorInfo) {
// You can also log the error to an error reporting service
// logErrorToMyService(error, errorInfo)
this.setState({error, info: errorInfo, stack: error.stack})
}
render() {
if (this.state.hasError) {
// You can render any custom fallback UI
return <h4>Something went wrong!</h4>;
}
return this.props.children;
}
}
export default ErrorBoundary
您可以根据需要呈现
error
、
info
和
stack
。您可以使用“react-json-view”包来很好地呈现
error
和
stack
。
并使用错误边界包装您的
App
,
<ErrorBoundary>
<App />
</ErrorBoundary>
Amila Senadheera
2021-04-29
我们最终重定向到 /error?... ,并使用自定义参数字符串告诉 Error 组件要显示什么。设置 Error 对象时,我们设置了要捕获的所有数据项。
const [errorObj, setErrorObj] = useState({});
来自 Ajax,可能设置错误的位置:
catch (error) {
// We capture 2 data items for an error in a custom object: message and location.
// Any other data items can also be in this custom object.
setErrorObj({message: error.message, location: 'approvals.js: fetchTeleworkInfo'});
}
渲染时:
errorObj.message
?
<Redirect to={generatePath('./error?msg=:errorMessage',
{errorMessage: formatError(errorObj)})} />
:
{/* Continue with normal render */}
<div>...</div>
实用函数
formatError
将从 Error 对象生成一些编码字符串:
// Format error object into a string (expects errorObj.message and errorObj.location fields)
// Error string is encoded (and decoded in the Error component) to support URL passing
export function formatError(errorObj) {
let result = '';
if (errorObj) {
if (errorObj.message) {
result += errorObj.message;
}
if (errorObj.location) {
result += ' (' + errorObj.location + ')';
}
}
return encodeURIComponent(result);
}
Error 组件可以通过 prop 或 URL 工作。这是它如何读取 URL 参数的一个示例:
export default function Error(props) {
// Obtain URL Params (optional)
// ----------------------------
const queryStr = new URLSearchParams(useLocation().search);
let message = null;
if (props.msg) { // Error string from property
message = props.msg;
} else if (queryStr.get("msg")) { // Error string from React-Router URL param
message = queryStr.get("msg");
}
// Decode string since it always comes in encoded
if (message) {
message = decodeURIComponent(message);
}
然后,Error 组件可以根据需要呈现/格式化错误并检查
message
字符串,例如
{message &&
<div>..</div>
}
gene b.
2022-03-01