Skip to content

Commit

Permalink
Don't convert error to string (#36804)
Browse files Browse the repository at this point in the history
Stack trace disappears when error is converted to string.
I changed the types in `log.ts` to match `console.log`/`console.error`/`console.warn`.

fixes #31591
  • Loading branch information
hanneslund committed May 11, 2022
1 parent 6f344e6 commit 2e13534
Show file tree
Hide file tree
Showing 7 changed files with 95 additions and 11 deletions.
14 changes: 7 additions & 7 deletions packages/next/build/output/log.ts
Expand Up @@ -10,30 +10,30 @@ export const prefixes = {
trace: chalk.magenta('trace') + ' -',
}

export function wait(...message: string[]) {
export function wait(...message: any[]) {
console.log(prefixes.wait, ...message)
}

export function error(...message: string[]) {
export function error(...message: any[]) {
console.error(prefixes.error, ...message)
}

export function warn(...message: string[]) {
export function warn(...message: any[]) {
console.warn(prefixes.warn, ...message)
}

export function ready(...message: string[]) {
export function ready(...message: any[]) {
console.log(prefixes.ready, ...message)
}

export function info(...message: string[]) {
export function info(...message: any[]) {
console.log(prefixes.info, ...message)
}

export function event(...message: string[]) {
export function event(...message: any[]) {
console.log(prefixes.event, ...message)
}

export function trace(...message: string[]) {
export function trace(...message: any[]) {
console.log(prefixes.trace, ...message)
}
8 changes: 4 additions & 4 deletions packages/next/server/dev/next-dev-server.ts
Expand Up @@ -693,7 +693,7 @@ export default class DevServer extends Server {
) {
let usedOriginalStack = false

if (isError(err) && err.name && err.stack && err.message) {
if (isError(err) && err.stack) {
try {
const frames = parseStack(err.stack!)
const frame = frames[0]
Expand Down Expand Up @@ -751,11 +751,11 @@ export default class DevServer extends Server {

if (!usedOriginalStack) {
if (type === 'warning') {
Log.warn(err + '')
Log.warn(err)
} else if (type) {
Log.error(`${type}:`, err + '')
Log.error(`${type}:`, err)
} else {
Log.error(err + '')
Log.error(err)
}
}
}
Expand Down
5 changes: 5 additions & 0 deletions test/integration/custom-server/server.js
Expand Up @@ -18,6 +18,11 @@ app.prepare().then(() => {
return app.render(req, res, '/no-query')
}

if (req.url === '/unhandled-rejection') {
Promise.reject(new Error('unhandled rejection'))
return res.end('ok')
}

if (/setAssetPrefix/.test(req.url)) {
app.setAssetPrefix(`http://127.0.0.1:${port}`)
} else if (/setEmptyAssetPrefix/.test(req.url)) {
Expand Down
22 changes: 22 additions & 0 deletions test/integration/custom-server/test/index.test.js
Expand Up @@ -216,4 +216,26 @@ describe('Custom Server', () => {
expect(data).toMatch(/hello world/)
})
})

describe('unhandled rejection', () => {
afterEach(() => killApp(server))

it('stderr should include error message and stack trace', async () => {
let stderr = ''
await startServer(
{},
{
onStderr(msg) {
stderr += msg || ''
},
}
)
await fetchViaHTTP(appPort, '/unhandled-rejection')
await check(() => stderr, /unhandledRejection/)
expect(stderr).toContain(
'error - unhandledRejection: Error: unhandled rejection'
)
expect(stderr).toContain('server.js:22:22')
})
})
})
@@ -0,0 +1,12 @@
export default function Page() {
return <p>getServerSideProps page</p>
}

export async function getServerSideProps() {
setTimeout(() => {
throw new Error()
}, 10)
return {
props: {},
}
}
@@ -0,0 +1,12 @@
export default function Page() {
return <p>getServerSideProps page</p>
}

export async function getServerSideProps() {
setTimeout(() => {
Promise.reject(new Error())
}, 10)
return {
props: {},
}
}
33 changes: 33 additions & 0 deletions test/integration/server-side-dev-errors/test/index.test.js
Expand Up @@ -11,6 +11,7 @@ import {
hasRedbox,
getRedboxSource,
} from 'next-test-utils'
import stripAnsi from 'strip-ansi'

const appDir = join(__dirname, '../')
const gspPage = join(appDir, 'pages/gsp.js')
Expand Down Expand Up @@ -213,6 +214,22 @@ describe('server-side dev errors', () => {
}, 'success')
})

it('should show server-side error for uncaught empty rejection correctly', async () => {
const stderrIdx = stderr.length
await webdriver(appPort, '/uncaught-empty-rejection')

await check(async () => {
const cleanStderr = stripAnsi(stderr.slice(stderrIdx))

return cleanStderr.includes('pages/uncaught-empty-rejection.js') &&
cleanStderr.includes('7:19') &&
cleanStderr.includes('getServerSideProps') &&
cleanStderr.includes('new Error()')
? 'success'
: cleanStderr
}, 'success')
})

it('should show server-side error for uncaught exception correctly', async () => {
const stderrIdx = stderr.length
await webdriver(appPort, '/uncaught-exception')
Expand All @@ -228,4 +245,20 @@ describe('server-side dev errors', () => {
: err
}, 'success')
})

it('should show server-side error for uncaught empty exception correctly', async () => {
const stderrIdx = stderr.length
await webdriver(appPort, '/uncaught-empty-exception')

await check(async () => {
const cleanStderr = stripAnsi(stderr.slice(stderrIdx))

return cleanStderr.includes('pages/uncaught-empty-exception.js') &&
cleanStderr.includes('7:10') &&
cleanStderr.includes('getServerSideProps') &&
cleanStderr.includes('new Error()')
? 'success'
: cleanStderr
}, 'success')
})
})

0 comments on commit 2e13534

Please sign in to comment.