Skip to content

Commit 2f505cb

Browse files
committed
Add stack trace
1 parent 32a4d9e commit 2f505cb

File tree

1 file changed

+89
-7
lines changed

1 file changed

+89
-7
lines changed

site/src/components/RuntimeErrorState/RuntimeErrorState.tsx

Lines changed: 89 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import Link from "@material-ui/core/Link"
33
import { makeStyles } from "@material-ui/core/styles"
44
import RefreshOutlined from "@material-ui/icons/RefreshOutlined"
55
import { BuildInfoResponse } from "api/typesGenerated"
6+
import { CopyButton } from "components/CopyButton/CopyButton"
67
import { CoderIcon } from "components/Icons/CoderIcon"
78
import { FullScreenLoader } from "components/Loader/FullScreenLoader"
89
import { Stack } from "components/Stack/Stack"
@@ -17,7 +18,9 @@ export type RuntimeErrorStateProps = { error: Error }
1718

1819
export const RuntimeErrorState: FC<RuntimeErrorStateProps> = ({ error }) => {
1920
const styles = useStyles()
20-
const [shouldDisplayMessage, setShouldDisplayMessage] = useState(false)
21+
const [checkingError, setCheckingError] = useState(true)
22+
const [staticBuildInfo, setStaticBuildInfo] = useState<BuildInfoResponse>()
23+
const coderVersion = staticBuildInfo?.version
2124

2225
// We use an effect to show a loading state if the page is trying to reload
2326
useEffect(() => {
@@ -34,17 +37,23 @@ export const RuntimeErrorState: FC<RuntimeErrorStateProps> = ({ error }) => {
3437
return
3538
}
3639

37-
setShouldDisplayMessage(true)
40+
setCheckingError(false)
3841
}, [error.message])
3942

43+
useEffect(() => {
44+
if (!checkingError) {
45+
setStaticBuildInfo(getStaticBuildInfo())
46+
}
47+
}, [checkingError])
48+
4049
return (
4150
<>
4251
<Helmet>
4352
<title>Something went wrong...</title>
4453
</Helmet>
45-
{shouldDisplayMessage ? (
46-
<Margins size="small" className={styles.root}>
47-
<div>
54+
{!checkingError ? (
55+
<Margins className={styles.root}>
56+
<div className={styles.innerRoot}>
4857
<CoderIcon className={styles.logo} />
4958
<h1 className={styles.title}>Something went wrong...</h1>
5059
<p className={styles.text}>
@@ -57,7 +66,9 @@ export const RuntimeErrorState: FC<RuntimeErrorStateProps> = ({ error }) => {
5766
<Link
5867
href={`https://github.com/coder/coder/issues/new?body=${encodeURIComponent(
5968
[
60-
["**Version**", getStaticBuildInfo()].join("\n"),
69+
["**Version**", coderVersion ?? "-- Set version --"].join(
70+
"\n",
71+
),
6172
["**Path**", "`" + location.pathname + "`"].join("\n"),
6273
["**Error**", "```\n" + error.stack + "\n```"].join("\n"),
6374
].join("\n\n"),
@@ -81,6 +92,22 @@ export const RuntimeErrorState: FC<RuntimeErrorStateProps> = ({ error }) => {
8192
Go to dashboard
8293
</Button>
8394
</Stack>
95+
{error.stack && (
96+
<div className={styles.stack}>
97+
<div className={styles.stackHeader}>
98+
Stacktrace
99+
<CopyButton
100+
buttonClassName={styles.copyButton}
101+
text={error.stack}
102+
tooltipTitle="Copy stacktrace"
103+
/>
104+
</div>
105+
<pre className={styles.stackCode}>{error.stack}</pre>
106+
</div>
107+
)}
108+
{coderVersion && (
109+
<div className={styles.version}>Version: {coderVersion}</div>
110+
)}
84111
</div>
85112
</Margins>
86113
) : (
@@ -100,7 +127,7 @@ const getStaticBuildInfo = () => {
100127
try {
101128
return JSON.parse(buildInfoJson) as BuildInfoResponse
102129
} catch {
103-
return "-- Set the version --"
130+
return undefined
104131
}
105132
}
106133
}
@@ -114,8 +141,11 @@ const useStyles = makeStyles((theme) => ({
114141
alignItems: "center",
115142
justifyContent: "center",
116143
minHeight: "100vh",
144+
maxWidth: theme.spacing(75),
117145
},
118146

147+
innerRoot: { width: "100%" },
148+
119149
logo: {
120150
fontSize: theme.spacing(8),
121151
},
@@ -131,4 +161,56 @@ const useStyles = makeStyles((theme) => ({
131161
lineHeight: "160%",
132162
marginBottom: theme.spacing(4),
133163
},
164+
165+
stack: {
166+
backgroundColor: theme.palette.background.paper,
167+
border: `1px solid ${theme.palette.divider}`,
168+
borderRadius: 4,
169+
marginTop: theme.spacing(8),
170+
display: "block",
171+
textAlign: "left",
172+
},
173+
174+
stackHeader: {
175+
fontSize: 10,
176+
textTransform: "uppercase",
177+
fontWeight: 600,
178+
letterSpacing: 1,
179+
padding: theme.spacing(1, 1, 1, 2),
180+
backgroundColor: theme.palette.background.paperLight,
181+
borderBottom: `1px solid ${theme.palette.divider}`,
182+
color: theme.palette.text.secondary,
183+
display: "flex",
184+
flexAlign: "center",
185+
justifyContent: "space-between",
186+
alignItems: "center",
187+
},
188+
189+
stackCode: {
190+
padding: theme.spacing(2),
191+
margin: 0,
192+
wordWrap: "break-word",
193+
whiteSpace: "break-spaces",
194+
},
195+
196+
copyButton: {
197+
backgroundColor: "transparent",
198+
border: 0,
199+
borderRadius: 999,
200+
minHeight: theme.spacing(4),
201+
minWidth: theme.spacing(4),
202+
height: theme.spacing(4),
203+
width: theme.spacing(4),
204+
205+
"& svg": {
206+
width: 16,
207+
height: 16,
208+
},
209+
},
210+
211+
version: {
212+
marginTop: theme.spacing(4),
213+
fontSize: 12,
214+
color: theme.palette.text.secondary,
215+
},
134216
}))

0 commit comments

Comments
 (0)