forked from XiaoMo/ChatGPT-Next-Web
76 lines
2.0 KiB
TypeScript
76 lines
2.0 KiB
TypeScript
import React from "react";
|
|
import { IconButton } from "./button";
|
|
import GithubIcon from "../icons/github.svg";
|
|
import ResetIcon from "../icons/reload.svg";
|
|
import { ISSUE_URL } from "../constant";
|
|
import Locale from "../locales";
|
|
import { downloadAs } from "../utils";
|
|
import { showConfirm } from "./ui-lib";
|
|
|
|
interface IErrorBoundaryState {
|
|
hasError: boolean;
|
|
error: Error | null;
|
|
info: React.ErrorInfo | null;
|
|
}
|
|
|
|
export class ErrorBoundary extends React.Component<any, IErrorBoundaryState> {
|
|
constructor(props: any) {
|
|
super(props);
|
|
this.state = { hasError: false, error: null, info: null };
|
|
}
|
|
|
|
componentDidCatch(error: Error, info: React.ErrorInfo) {
|
|
// Update state with error details
|
|
this.setState({ hasError: true, error, info });
|
|
}
|
|
|
|
clearAndSaveData() {
|
|
try {
|
|
downloadAs(
|
|
JSON.stringify(localStorage),
|
|
"chatgpt-next-web-snapshot.json",
|
|
);
|
|
} finally {
|
|
localStorage.clear();
|
|
location.reload();
|
|
}
|
|
}
|
|
|
|
render() {
|
|
if (this.state.hasError) {
|
|
// Render error message
|
|
return (
|
|
<div className="error">
|
|
<h2>Oops, something went wrong!</h2>
|
|
<pre>
|
|
<code>{this.state.error?.toString()}</code>
|
|
<code>{this.state.info?.componentStack}</code>
|
|
</pre>
|
|
|
|
<div style={{ display: "flex", justifyContent: "space-between" }}>
|
|
<a href={ISSUE_URL} className="report">
|
|
<IconButton
|
|
text="Report This Error"
|
|
icon={<GithubIcon />}
|
|
bordered
|
|
/>
|
|
</a>
|
|
<IconButton
|
|
icon={<ResetIcon />}
|
|
text="Clear All Data"
|
|
onClick={async () => {
|
|
if (await showConfirm(Locale.Settings.Danger.Reset.Confirm)) {
|
|
this.clearAndSaveData();
|
|
}
|
|
}}
|
|
bordered
|
|
/>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
// if no error occurred, render children
|
|
return this.props.children;
|
|
}
|
|
}
|