Skip to content
Merged
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import React from 'react'
import type { StackFramesGroup } from '../../helpers/group-stack-frames-by-framework'
import { CallStackFrame } from './CallStackFrame'
import { FrameworkIcon } from './FrameworkIcon'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import type { StackFrame } from 'next/dist/compiled/stacktrace-parser'
// import type { OriginalStackFrameResponse } from '../../middleware'

export type OriginalStackFrame =
| {
Expand Down
18 changes: 12 additions & 6 deletions packages/next/src/server/lib/trace/tracer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -284,13 +284,19 @@ class NextTracerImpl implements NextTracer {
}

const result = fn(span)

if (isPromise(result)) {
result
.then(
() => span.end(),
(err) => closeSpanWithError(span, err)
)
// If there's error make sure it throws
return result
.then((res) => {
span.end()
// Need to pass down the promise result,
// it could be react stream response with error { error, stream }
return res
})
.catch((err) => {
closeSpanWithError(span, err)
throw err
})
.finally(onCleanup)
} else {
span.end()
Expand Down
7 changes: 4 additions & 3 deletions packages/react-dev-overlay/src/middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,8 @@ function getOverlayMiddleware(options: OverlayMiddlewareOptions) {
if (
!(
(frame.file?.startsWith('webpack-internal:///') ||
frame.file?.startsWith('file://')) &&
frame.file?.startsWith('file://') ||
frame.file?.startsWith('webpack:///')) &&
Boolean(parseInt(frame.lineNumber?.toString() ?? '', 10))
)
) {
Expand All @@ -331,11 +332,11 @@ function getOverlayMiddleware(options: OverlayMiddlewareOptions) {
}

const moduleId: string = frame.file.replace(
/^(webpack-internal:\/\/\/|file:\/\/)/,
/webpack-internal:(\/)+|file:\/\//,
''
)
const modulePath = frame.file.replace(
/^(webpack-internal:\/\/\/|file:\/\/)(\(.*\)\/)?/,
/webpack-internal:(\/)+|file:\/\/(\(.*\)\/)?/,
''
)

Expand Down
25 changes: 24 additions & 1 deletion test/development/acceptance-app/rsc-runtime-errors.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { FileRef, createNextDescribe } from 'e2e-utils'
import {
check,
getRedboxDescription,
getRedboxSource,
hasRedbox,
shouldRunTurboDevTest,
} from 'next-test-utils'
Expand Down Expand Up @@ -88,14 +89,36 @@ createNextDescribe(
)

const browser = await next.browser('/server')

await check(
async () => ((await hasRedbox(browser, true)) ? 'success' : 'fail'),
/success/
)

const errorDescription = await getRedboxDescription(browser)

expect(errorDescription).toContain(`Error: alert is not defined`)
})

it('should show the userland code error trace when fetch failed error occurred', async () => {
await next.patchFile(
'app/server/page.js',
outdent`
export default async function Page() {
await fetch('http://locahost:3000/xxxx')
return 'page'
}
`
)
const browser = await next.browser('/server')
await check(
async () => ((await hasRedbox(browser, true)) ? 'success' : 'fail'),
/success/
)

const source = await getRedboxSource(browser)
// Can show the original source code
expect(source).toContain('app/server/page.js')
expect(source).toContain(`await fetch('http://locahost:3000/xxxx')`)
})
}
)
4 changes: 3 additions & 1 deletion test/turbopack-tests-manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -1185,7 +1185,9 @@
"Error overlay - RSC runtime errors should show runtime errors if invalid client API from node_modules is executed",
"Error overlay - RSC runtime errors should show runtime errors if invalid server API from node_modules is executed"
],
"failed": [],
"failed": [
"Error overlay - RSC runtime errors should show the userland code error trace when fetch failed error occurred"
],
"pending": [],
"flakey": [],
"runtimeError": false
Expand Down