Skip to content

Commit

Permalink
fix(default-layout): handle render errors with no Error instance in b…
Browse files Browse the repository at this point in the history
…oundary (#2754)

Fixes an issue where (for some reason) components can crash during rendering
without emitting an Error instance. This leads to the error screen crashing
when attempting to extract the stack trace from it.

With this change, we render a generic unknown error if we don't receive any
error instance, and check for a stack property before attempting to use it.

For additional safety, we also check for the info property and the component
stack being present before attempting to use it.
  • Loading branch information
rexxars committed Sep 9, 2021
1 parent c4b3653 commit 22c123f
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 9 deletions.
25 changes: 17 additions & 8 deletions packages/@sanity/default-layout/src/main/ErrorScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,15 +72,24 @@ function ErrorScreen(props: Props) {

{showErrorDetails && (
<>
<div className={styles.stack}>
<h3>Stack trace:</h3>
<pre>{formatStack(limitStackLength(getErrorWithStack(error)))}</pre>
</div>
{error.stack ? (
<div className={styles.stack}>
<h3>Stack trace:</h3>
<pre>{formatStack(limitStackLength(getErrorWithStack(error)))}</pre>
</div>
) : (
<div className={styles.stack}>
<h3>Error:</h3>
<pre>{error.message}</pre>
</div>
)}

<div className={styles.stack}>
<h3>Component stack:</h3>
<pre>{info.componentStack.replace(/^\s*\n+/, '')}</pre>
</div>
{info && info.componentStack && (
<div className={styles.stack}>
<h3>Component stack:</h3>
<pre>{info.componentStack.replace(/^\s*\n+/, '')}</pre>
</div>
)}
</>
)}
</div>
Expand Down
8 changes: 7 additions & 1 deletion packages/@sanity/default-layout/src/main/RenderTool.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ import ErrorScreen from './ErrorScreen'

declare const __DEV__: boolean

const defaultUnknownError = {
message: 'An unknown error occured while rendering',
}

interface Props {
tool: string
}
Expand Down Expand Up @@ -56,7 +60,9 @@ export default class RenderTool extends React.Component<Props> {
return (
<ErrorScreen
activeTool={this.getActiveTool()}
error={error}
// Some (rare) errors doesn't seem to have any Error instance attached
// In these cases, default to an error-like object with a generic message
error={error || defaultUnknownError}
info={info}
onRetry={this.handleRetry}
onShowDetails={this.handleShowDetails}
Expand Down

2 comments on commit 22c123f

@vercel
Copy link

@vercel vercel bot commented on 22c123f Sep 9, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

test-studio – ./

test-studio.sanity.build
test-studio-git-next.sanity.build

@vercel
Copy link

@vercel vercel bot commented on 22c123f Sep 9, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

perf-studio – ./

perf-studio.sanity.build
perf-studio-git-next.sanity.build

Please sign in to comment.