tutu/src/UnexpectedError.tsx

99 lines
2.4 KiB
TypeScript

import { Button } from "@suid/material";
import { Component, createResource } from "solid-js";
import { css } from "solid-styled";
const UnexpectedError: Component<{ error?: any }> = (props) => {
const [errorMsg] = createResource(
() => props.error,
async (err) => {
if (err instanceof Error) {
const mod = await import("stacktrace-js");
try {
const stacktrace = await mod.fromError(err);
const strackMsg = stacktrace
.map(
(entry) =>
`${entry.functionName ?? "<unknown>"}@${entry.fileName}:(${entry.lineNumber}:${entry.columnNumber})`,
)
.join("\n");
return `${err.name}: ${err.message}\n${strackMsg}`;
} catch (reason) {
return `<failed to build the stacktrace of "${err}"...>\n${reason}\n${JSON.stringify(
{
name: err.name,
stack: err.stack,
cause: err.cause,
message: err.message,
},
undefined,
2,
)}`;
}
}
return err.toString();
},
);
css`
main {
padding: calc(var(--safe-area-inset-top) + 20px)
calc(var(--safe-area-inset-right) + 20px)
calc(var(--safe-area-inset-bottom) + 20px)
calc(var(--safe-area-inset-left) + 20px);
}
details {
max-width: 100vw;
max-width: 100dvw;
overflow: auto;
& * {
user-select: all;
}
summary {
position: sticky;
left: 0;
top: 0;
user-select: none;
}
}
.actions {
margin-top: 20px;
margin-bottom: 20px;
}
`;
return (
<main>
<h1>Oh, it is our fault.</h1>
<p>There is an unexpected error in our app, and it's not your fault.</p>
<p>
You can restart the app to see if this guy is gone. If you meet this guy
repeatly, please report to us.
</p>
<div class="actions">
<Button
onClick={() => window.location.replace("/")}
variant="contained"
>
Restart App
</Button>
</div>
<details>
<summary>
{errorMsg.loading ? "Generating " : " "}Technical Infomation
</summary>
<pre>
On: {window.location.href} <br />
{errorMsg()}
</pre>
</details>
</main>
);
};
export default UnexpectedError;