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

[SourceMap] prepareStackTrace patch minifies server stack trace #74646

Open
troyt-42 opened this issue Jan 8, 2025 · 4 comments
Open

[SourceMap] prepareStackTrace patch minifies server stack trace #74646

troyt-42 opened this issue Jan 8, 2025 · 4 comments
Labels
bug Issue was opened via the bug report template. linear: next Confirmed issue that is tracked by the Next.js team. Runtime Related to Node.js or Edge Runtime with Next.js.

Comments

@troyt-42
Copy link

troyt-42 commented Jan 8, 2025

Link to the code that reproduces this issue

https://github.com/troyt-42/nextjs-source-map

To Reproduce

  1. Checkout https://github.com/troyt-42/nextjs-source-map
  2. Install dependencies
  3. Generate a production build: yarn build
  4. Start the server with source map enabled: NODE_OPTIONS=--enable-source-maps yarn start
  5. Access localhost:3000

Current vs. Expected behavior

Current:
The manual log's stack trace is minified even we have the page.js.map file generated

Where am I: Error: 
    at i (.../nextjs-source-map/.next/server/app/page.js:1:31591)
    at ek (.../nextjs-source-map/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:84:13368)
    at e (.../nextjs-source-map/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:84:17266)
    at e$ (.../nextjs-source-map/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:84:17728)
    at Array.toJSON (.../nextjs-source-map/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:84:14874)
    at stringify (<anonymous>)
    at eU (.../nextjs-source-map/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:84:26231)
    at eB (.../nextjs-source-map/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:84:26461)
    at eq (.../nextjs-source-map/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:84:27015)
    at AsyncLocalStorage.run (node:async_hooks:346:14)

Expected:
After commenting out this line:

errorConstructor.prepareStackTrace = prepareUnsourcemappedStackTrace
, I can see the source-mapped stack trace

Where am I: Error
    at i (webpack://nextjs-source-map/src/app/page.tsx:4:30)
    at renderFunctionComponent (webpack://next/dist/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.production.js:1006:15)
    at renderElement (webpack://next/dist/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.production.js:1082:12)
    at renderModelDestructive (webpack://next/dist/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.production.js:1121:1)
    at Array.toJSON (webpack://next/dist/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.production.js:1156:40)
    at stringify (<anonymous>)
    at emitChunk (webpack://next/dist/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.production.js:1734:43)
    at retryTask (webpack://next/dist/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.production.js:1755:11)
    at eq (webpack://next/dist/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.production.js:1803:7)
    at AsyncLocalStorage.run (node:async_hooks:346:14)

Provide environment information

Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 23.6.0: Wed Jul 31 20:48:04 PDT 2024; root:xnu-10063.141.1.700.5~1/RELEASE_ARM64_T6030
  Available memory (MB): 36864
  Available CPU cores: 12
Binaries:
  Node: 20.12.2
  npm: 10.8.1
  Yarn: 1.22.22
  pnpm: 9.15.3
Relevant Packages:
  next: 15.1.3
  eslint-config-next: 15.1.3
  react: 19.0.0
  react-dom: 19.0.0
  typescript: 5.7.2
Next.js Config:
  output: N/A

Which area(s) are affected? (Select all that apply)

Runtime

Which stage(s) are affected? (Select all that apply)

next start (local)

Additional context

After reviewing patch-error-inspect.ts, it seems intentional that prepareStackTrace prevents error.stack from being source-mapped. If this is the intended behavior, there may be an issue in the downstream code.

This behavior is causing maintenance challenges for Faire after upgrading to Next.js version 15.1.3. Having source-mapped stack traces is critical for efficient debugging, and the absence of this feature significantly hinders our ability to troubleshoot issues.

@troyt-42 troyt-42 added the bug Issue was opened via the bug report template. label Jan 8, 2025
@github-actions github-actions bot added the Runtime Related to Node.js or Edge Runtime with Next.js. label Jan 8, 2025
@eps1lon eps1lon added the linear: next Confirmed issue that is tracked by the Next.js team. label Jan 8, 2025
@eps1lon
Copy link
Member

eps1lon commented Jan 8, 2025

This is an unfortunate side-effect of how we ensure source-maps work in both terminal and attached debuggers. Once you log the actual error object instead of just the stack, sourcemapping works as intended:

-console.log(new Error().stack)
+console.log(new Error())
Where am I: Error: 
    at i (webpack://nextjs-source-map/src/app/page.tsx:4:29)
    at stringify (<anonymous>)

function names are not mapped due to a Node.js bug that would result in incorrect names. We're waiting on https://github.com/tc39/ecma426/blob/main/proposals/scopes.md to fix this.

Keep in mind that you should not run a production server with --enable-sourcemaps since that means sourcemaps are applied eagerly which severely affects performance. Instead, lobby for your log drain to apply sourcemaps lazily or use other 3rd party error tracking tools like Sentry.

@troyt-42
Copy link
Author

troyt-42 commented Jan 8, 2025

This is an unfortunate side-effect of how we ensure source-maps work in both terminal and attached debuggers. Once you log the actual error object instead of just the stack, sourcemapping works as intended:

-console.log(new Error().stack)
+console.log(new Error())
Where am I: Error: 
    at i (webpack://nextjs-source-map/src/app/page.tsx:4:29)
    at stringify (<anonymous>)

function names are not mapped due to a Node.js bug that would result in incorrect names. We're waiting on https://github.com/tc39/ecma426/blob/main/proposals/scopes.md to fix this.

Keep in mind that you should not run a production server with --enable-sourcemaps since that means sourcemaps are applied eagerly which severely affects performance. Instead, lobby for your log drain to apply sourcemaps lazily or use other 3rd party error tracking tools like Sentry.

Thanks for the information! The main reason we use --enable-sourcemaps is to support local debugging and verify fixes. However, the inability to access Error().stack means we can’t properly process error logs in our custom logger. Our logger reads all relevant information from the error object and generates a new error object with additional custom details attached.

We could potentially mitigate this by retaining the original error object and attaching new information directly to it instead. That said, I’d like to understand whether fixing this side effect would be difficult. Not being able to access a raw NodeJS API in our custom servers is a limitation I want to remove.

@eps1lon
Copy link
Member

eps1lon commented Jan 8, 2025

Our logger reads all relevant information from the error object and generates a new error object with additional custom details attached.

I'd need to know more about how your logger is implemented. Though if it creates new error objects and then stashes the stack somewhere else, debuggers will not be able to sourcemap it properly either.

That said, I’d like to understand whether fixing this side effect would be difficult.

It's not possible if you manually extract error.stack and expect that to be sourcemapped. Though manually sourcemapping is pretty straight forward with Node.js APIs. You already found already all the missing pieces in patch-error-inspect. You can skip the bundler paths and use https://nodejs.org/api/module.html#class-modulesourcemap instead of the source-map library.

@troyt-42
Copy link
Author

troyt-42 commented Jan 9, 2025

Got it. Here are the three potential options I’m considering:

  1. Patch Next.js to remove the prepareStackTrace override
    This seems like the simplest approach since it wouldn’t require modifying our custom logger. However, I’m uncertain about the potential side effects of this change, particularly whether Next.js relies on its prepareStackTrace override for other purposes (other than supporting debuggers ?).
  2. Accept the limit and modify our custom logger to avoid directly accessing the stack trace
    Instead of extracting the stack trace manually, we could pass the original Error object directly to console. But this doesn't resolve the limitation.
  3. Manually resolve source maps and apply them to unminify the stack trace
    This should unblock usage of Error.stack. However, I’m puzzled by why removing the line errorConstructor.prepareStackTrace = prepareUnsourcemappedStackTrace results in a properly source-mapped stack trace. It seems like Node.js initially provides a source-mapped trace, and Next.js overrides it to an unmapped one. Therefore, adding another manual step to resolve source maps might be redundant and could introduce inefficiencies ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Issue was opened via the bug report template. linear: next Confirmed issue that is tracked by the Next.js team. Runtime Related to Node.js or Edge Runtime with Next.js.
Projects
None yet
Development

No branches or pull requests

2 participants