Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(dev): only rewrite SSR stacktrace when possible #4248

Merged
merged 2 commits into from Jul 14, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 6 additions & 2 deletions packages/vite/src/node/server/index.ts
Expand Up @@ -48,7 +48,10 @@ import { TransformOptions as EsbuildTransformOptions } from 'esbuild'
import { DepOptimizationMetadata, optimizeDeps } from '../optimizer'
import { ssrLoadModule } from '../ssr/ssrModuleLoader'
import { resolveSSRExternal } from '../ssr/ssrExternal'
import { ssrRewriteStacktrace } from '../ssr/ssrStacktrace'
import {
rebindErrorStacktrace,
ssrRewriteStacktrace
} from '../ssr/ssrStacktrace'
import { createMissingImporterRegisterFn } from '../optimizer/registerMissing'
import { printServerUrls } from '../logger'
import { resolveHostname } from '../utils'
Expand Down Expand Up @@ -366,7 +369,8 @@ export async function createServer(
},
ssrFixStacktrace(e) {
if (e.stack) {
e.stack = ssrRewriteStacktrace(e.stack, moduleGraph)
const stacktrace = ssrRewriteStacktrace(e.stack, moduleGraph)
rebindErrorStacktrace(e, stacktrace)
}
},
listen(port?: number, isRestart?: boolean) {
Expand Down
7 changes: 4 additions & 3 deletions packages/vite/src/node/ssr/ssrModuleLoader.ts
Expand Up @@ -2,7 +2,7 @@ import fs from 'fs'
import path from 'path'
import { ViteDevServer } from '..'
import { cleanUrl, resolveFrom, unwrapId } from '../utils'
import { ssrRewriteStacktrace } from './ssrStacktrace'
import { rebindErrorStacktrace, ssrRewriteStacktrace } from './ssrStacktrace'
import {
ssrExportAllKey,
ssrModuleExportsKey,
Expand Down Expand Up @@ -141,9 +141,10 @@ async function instantiateModule(
ssrExportAll
)
} catch (e) {
e.stack = ssrRewriteStacktrace(e.stack, moduleGraph)
const stacktrace = ssrRewriteStacktrace(e.stack, moduleGraph)
rebindErrorStacktrace(e, stacktrace)
server.config.logger.error(
`Error when evaluating SSR module ${url}:\n${e.stack}`,
`Error when evaluating SSR module ${url}:\n${stacktrace}`,
{
timestamp: true,
clear: server.config.clearScreen
Expand Down
17 changes: 17 additions & 0 deletions packages/vite/src/node/ssr/ssrStacktrace.ts
Expand Up @@ -56,3 +56,20 @@ export function ssrRewriteStacktrace(
})
.join('\n')
}

export function rebindErrorStacktrace(e: Error, stacktrace: string): void {
const { configurable, writable } = Object.getOwnPropertyDescriptor(
e,
'stack'
)!
if (configurable) {
Object.defineProperty(e, 'stack', {
value: stacktrace,
enumerable: true,
configurable: true,
writable: true
})
} else if (writable) {
e.stack = stacktrace
}
Copy link
Member

Choose a reason for hiding this comment

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

Should we warn if neither configurable nor writable, so the dependency gets fixed?

Copy link
Member Author

@GrygrFlzr GrygrFlzr Jul 14, 2021

Choose a reason for hiding this comment

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

Hm, emitting the warning properly would require server instance, which wouldn't be accessible inside rebindErrorStacktrace. Would it be better to:

Pass in a server instance to have rebindErrorStacktrace emit the warning?

function rebindErrorStacktrace(e: Error, stacktrace: string, server: ViteDevServer): void

Return a boolean for success and have the respective consumers emit the warning? There probably would also be more context available for more detailed errors.

function rebindErrorStacktrace(e: Error, stacktrace: string): boolean

Copy link
Member

Choose a reason for hiding this comment

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

I'm thinking we should deprecate ssrRewriteStacktrace in favor of a SSRError extends Error subclass whose constructor takes a stack trace string. So for now, I vote to merge this PR as-is.

}