POST request handled as GET in nextjs route handlers
Is there an existing issue for this?
- [x] I have checked for existing issues https://github.com/getsentry/sentry-javascript/issues
- [x] I have reviewed the documentation https://docs.sentry.io/
- [x] I am using the latest SDK release https://github.com/getsentry/sentry-javascript/releases
How do you use Sentry?
Sentry Saas (sentry.io)
Which SDK are you using?
@sentry/nextjs
SDK Version
8.33.1
Framework Version
No response
Link to Sentry event
https://dev-curumas.sentry.io/issues/5968125190/?project=5591101&query=is%3Aunresolved%20issue.priority%3A%5Bhigh%2C%20medium%5D&referrer=issue-stream&statsPeriod=7d&stream_index=0
Reproduction Example/SDK Setup
No response
Steps to Reproduce
Repro: next-test-sentry-main.zip Follow the steps in the readme:
- npm install
- update DSN in the sentry config files
- npm run dev
- send a POST request to http://localhost:3000/api/test
Expected Result
The event in sentry has the POST request information including body.
Actual Result
The request in the Sentry event is treated as a GET request, even though the event is associated with the transaction POST /api/test (http.server)
Thanks for raising. For the next person reading this. We need to start filling the request interface properly: https://develop.sentry.dev/sdk/event-payloads/request/
I have worked around this issue in our code by adding an event processor which gets a clone of the request so .json() can be called once more. This can fail if there is no body, so that is something to keep in mind. Roughly looks like this, but I can imagine there is a better way 😄
type EventProcessorCreator = (
httpRequest: NextRequest,
status_code: number,
) => Promise<(event: Sentry.Event, hint: Sentry.EventHint) => Promise<Sentry.Event>>;
export const getRequestEventProcessor: EventProcessorCreator =
async (httpRequest, status_code) => async (event, hint) => {
const { request, contexts, breadcrumbs } = event;
const {
url,
method,
cookies,
nextUrl: { searchParams, pathname },
} = httpRequest;
return {
...event,
request: {
...request,
url,
query_string: Object.fromEntries(searchParams),
method: method,
data: await httpRequest.json(),
cookies: Object.fromEntries(cookies.getAll().map(({ name, value }) => [name, value])),
},
contexts: {
...contexts,
response: {
...(contexts?.response && { ...contexts.response }),
status_code,
},
},
transaction: `${method} ${pathname}`,
breadcrumbs: breadcrumbs?.map(value => ({
...value,
message: value.message ? stripAnsi(value.message) : '',
})),
};
};
// ...
const eventProcessor = await getRequestEventProcessor(request, status);
Sentry.withScope(scope => {
// ...
scope.addEventProcessor(eventProcessor);
});
Setting event.contexts.response directly gave TS errors
I attempted to reproduce the issue. Although the error was logged on the dashboard, I was unable to view the request section. You can check out the event details here.
To investigate further, I captured the event object being sent from the Next.js server to Sentry using the beforeSend function:
import * as Sentry from "@sentry/nextjs";
import { writeFile } from "fs";
Sentry.init({
dsn: "<DNS>",
tracesSampleRate: 1,
debug: false,
beforeSend(...args) {
writeFile("sentryEvent.json", JSON.stringify(args), () => {});
return args[0];
},
});
You can find the sentry-event.json file here. However, this event doesn't seem to include the request object.
@malay44 we can repro the issue. We just need to fix it. It's medium prio for us atm.
A PR closing this issue has just been released 🚀
This issue was referenced by PR #14084, which was included in the 8.36.0 release.