Skip to content

Commit

Permalink
feat(react-dev-overlay): accept preventDisplay prop to allow config of
Browse files Browse the repository at this point in the history
which errors are display (used by next live)
  • Loading branch information
natew committed Feb 16, 2022
1 parent 9dcb09a commit 3e7799e
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 40 deletions.
2 changes: 1 addition & 1 deletion packages/next/compiled/@next/react-dev-overlay/client.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions packages/react-dev-overlay/src/client.ts
Expand Up @@ -87,6 +87,7 @@ function onRefresh() {
Bus.emit({ type: Bus.TYPE_REFRESH })
}

export { getErrorByType } from './internal/helpers/getErrorByType'
export { getNodeError } from './internal/helpers/nodeStackFrames'
export { default as ReactDevOverlay } from './internal/ReactDevOverlay'
export {
Expand Down
28 changes: 27 additions & 1 deletion packages/react-dev-overlay/src/internal/ReactDevOverlay.tsx
Expand Up @@ -58,8 +58,14 @@ function reducer(state: OverlayState, ev: Bus.BusEvent): OverlayState {
}
}

type ErrorType = 'runtime' | 'build' | 'full-refresh'

const ReactDevOverlay: React.FunctionComponent = function ReactDevOverlay({
children,
preventDisplay,
}: {
children?: React.ReactNode
preventDisplay?: ErrorType[]
}) {
const [state, dispatch] = React.useReducer<
React.Reducer<OverlayState, Bus.BusEvent>
Expand Down Expand Up @@ -90,6 +96,7 @@ const ReactDevOverlay: React.FunctionComponent = function ReactDevOverlay({
const isAboutToFullRefresh = state.isAboutToFullRefresh

const isMounted = hasBuildError || hasRuntimeErrors || isAboutToFullRefresh

return (
<React.Fragment>
<ErrorBoundary onError={onComponentError}>
Expand All @@ -101,7 +108,16 @@ const ReactDevOverlay: React.FunctionComponent = function ReactDevOverlay({
<Base />
<ComponentStyles />

{hasBuildError ? (
{shouldPreventDisplay(
hasBuildError
? 'build'
: hasRuntimeErrors
? 'runtime'
: isAboutToFullRefresh
? 'full-refresh'
: null,
preventDisplay
) ? null : hasBuildError ? (
<BuildError message={state.buildError!} />
) : hasRuntimeErrors ? (
<Errors errors={state.errors} />
Expand All @@ -114,4 +130,14 @@ const ReactDevOverlay: React.FunctionComponent = function ReactDevOverlay({
)
}

const shouldPreventDisplay = (
errorType?: ErrorType | null,
preventType?: ErrorType[] | null
) => {
if (!preventType || !errorType) {
return false
}
return preventType.includes(errorType)
}

export default ReactDevOverlay
38 changes: 1 addition & 37 deletions packages/react-dev-overlay/src/internal/container/Errors.tsx
Expand Up @@ -14,12 +14,9 @@ import {
import { LeftRightDialogHeader } from '../components/LeftRightDialogHeader'
import { Overlay } from '../components/Overlay'
import { Toast } from '../components/Toast'
import { getErrorByType, ReadyRuntimeError } from '../helpers/getErrorByType'
import { isNodeError } from '../helpers/nodeStackFrames'
import { noop as css } from '../helpers/noop-template'
import {
getOriginalStackFrames,
OriginalStackFrame,
} from '../helpers/stack-frame'
import { RuntimeError } from './RuntimeError'

export type SupportedErrorEvent = {
Expand All @@ -28,13 +25,6 @@ export type SupportedErrorEvent = {
}
export type ErrorsProps = { errors: SupportedErrorEvent[] }

export type ReadyRuntimeError = {
id: number

runtime: true
error: Error
frames: OriginalStackFrame[]
}
type ReadyErrorEvent = ReadyRuntimeError

function getErrorSignature(ev: SupportedErrorEvent): string {
Expand Down Expand Up @@ -82,32 +72,6 @@ const HotlinkedText: React.FC<{
)
}

async function getErrorByType(
ev: SupportedErrorEvent
): Promise<ReadyErrorEvent> {
const { id, event } = ev
switch (event.type) {
case TYPE_UNHANDLED_ERROR:
case TYPE_UNHANDLED_REJECTION: {
return {
id,
runtime: true,
error: event.reason,
frames: await getOriginalStackFrames(
isNodeError(event.reason),
event.frames
),
}
}
default: {
break
}
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const _: never = event
throw new Error('type system invariant violation')
}

export const Errors: React.FC<ErrorsProps> = function Errors({ errors }) {
const [lookups, setLookups] = React.useState(
{} as { [eventId: string]: ReadyErrorEvent }
Expand Down
@@ -1,9 +1,9 @@
import * as React from 'react'
import { StackFrame } from 'stacktrace-parser'
import { CodeFrame } from '../components/CodeFrame'
import { ReadyRuntimeError } from '../helpers/getErrorByType'
import { noop as css } from '../helpers/noop-template'
import { getFrameSource, OriginalStackFrame } from '../helpers/stack-frame'
import { ReadyRuntimeError } from './Errors'

export type RuntimeErrorProps = { error: ReadyRuntimeError }

Expand Down
37 changes: 37 additions & 0 deletions packages/react-dev-overlay/src/internal/helpers/getErrorByType.ts
@@ -0,0 +1,37 @@
import { TYPE_UNHANDLED_ERROR, TYPE_UNHANDLED_REJECTION } from '../bus'
import { SupportedErrorEvent } from '../container/Errors'
import { isNodeError } from './nodeStackFrames'
import { getOriginalStackFrames, OriginalStackFrame } from './stack-frame'

export type ReadyRuntimeError = {
id: number
runtime: true
error: Error
frames: OriginalStackFrame[]
}

export async function getErrorByType(
ev: SupportedErrorEvent
): Promise<ReadyRuntimeError> {
const { id, event } = ev
switch (event.type) {
case TYPE_UNHANDLED_ERROR:
case TYPE_UNHANDLED_REJECTION: {
return {
id,
runtime: true,
error: event.reason,
frames: await getOriginalStackFrames(
isNodeError(event.reason),
event.frames
),
}
}
default: {
break
}
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const _: never = event
throw new Error('type system invariant violation')
}

0 comments on commit 3e7799e

Please sign in to comment.