next.js
94414f78 - bugfix: Bad `next.route` on `pages` dir OTel spans for `404`s / `500`s (#77150)

Commit
181 days ago
bugfix: Bad `next.route` on `pages` dir OTel spans for `404`s / `500`s (#77150) ## Issue - Resolves https://github.com/vercel/next.js/issues/82102 ## What it Does Prevents the root span attribute `next.route` from being overwritten once set for a request. This resolves two issues: 1. Fixes `404`s and `500`s in the `pagesDir` overwriting `next.route` on OpenTelemetry root span 2. Removes redundant `/route` suffixes on `appDir` API Route Handler OTel span names ## Background The root OTel span (`BaseServer.handleRequest`) for requests in Next.js derives its `name` from its `next.route` attr, set by child spans through the `NextTracerImpl.setRootSpanAttribute` function. The problem is, when a page `404`s or `500`s, the rendering of the `404` or `500` page *also* sets `next.route`. This scrubs the root span of the original page's `next.route`, as if the user had requested the `/_not-found` or `/_error` page directly. For example, these two traces in `otel-desktop-viewer` are requests to the same URL, with the bottom having received an error thrown in `getServerSideProps`: <img width="328" alt="image" src="https://github.com/user-attachments/assets/855744b6-8720-4c5e-a5e5-b15cb95e43ca" /> This is not helpful at all! Further investigation shows that root spans all have the following behavior:: - Successful responses are correctly named after their path, e.g. `GET /foo` with `status_code: 200` - Not found responses on ALL paths are named `GET /_not-found` with `status_code: 404` - Erroring responses on ALL paths are named `GET /_error` with `status_code: 500` As another example, consider which `name` and `status_code` combo is more helpful: - `name: GET /_not-found`, `status_code: 404`, `http.target: /foo?page=10`, `next.route: /_not-found` (current) - **`name: GET /foo`**, `status_code: 404`, `http.target: /foo?page=10`, `next.route: /foo`, (desired) Clearly, replacing span names with `GET /_not-found` only removes information, as the "404"-ness is already indicated by the `status_code` span attribute. A search for `setRootSpanAttribute` confirms that this function is only used 4 times, all to set `next.route`: https://github.com/vercel/next.js/blob/6d7266e329a684b4e254c6a265f5b3ddb6e7b332/packages/next/src/server/api-utils/index.ts?plain=1#L28 https://github.com/vercel/next.js/blob/6d7266e329a684b4e254c6a265f5b3ddb6e7b332/packages/next/src/server/route-modules/app-route/module.ts?plain=1#L743 https://github.com/vercel/next.js/blob/6d7266e329a684b4e254c6a265f5b3ddb6e7b332/packages/next/src/server/base-server.ts?plain=1#L3732 https://github.com/vercel/next.js/blob/6d7266e329a684b4e254c6a265f5b3ddb6e7b332/packages/next/src/server/app-render/app-render.tsx?plain=1#L1333 So, we need to make sure `setRootSpanAttribute` does not overwrite `next.route` if it has already been set. This PR does that, and adds tests for `/_not-found` and `/_error` page cases (which were missing from the `e2e` test suite). ## Repro Repro: https://github.com/evankirkiles/nextjs-otel-span-name-errors Before (using `next.js@canary`): <img width="1773" height="1036" alt="SCR-20250727-suas" src="https://github.com/user-attachments/assets/94895bc7-8f09-4c55-ba3e-63191ac49ff7" /> After (using changes from this PR): <img width="1728" height="997" alt="image" src="https://github.com/user-attachments/assets/3f3a1fdd-0acd-4b00-a34d-3e8e3d49e09a" /> ## Fixing a bug - [x] Tests added. See: https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs
Author
Parents
Loading