sentry-javascript icon indicating copy to clipboard operation
sentry-javascript copied to clipboard

feat(node): Ensure request bodies are reliably captured for http requests

Open mydea opened this issue 1 year ago • 3 comments

This PR started out as trying to fix capturing request bodies for Koa.

Some investigation later, we found out that the fundamental problem was that we relied on the request body being on request.body, which is non-standard and thus does not necessarily works. It seems that in express this works because it under the hood writes the body there, but this is non-standard and rather undefined behavior. For other frameworks (e.g. Koa and probably more) this did not work, the body was not on the request and thus never captured. We also had no test coverage for this overall.

This PR ended up doing a few things:

  • Add tests for this for express and koa
  • Streamline types for sdkProcessingMetadata - this used to be any, which lead to any usage of this not really being typed at all. I added proper types for this now.
  • Generic extraction of the http request body in the http instrumentation - this should now work for any node framework

Most importantly, I opted to not force this into the existing, rather complicated and hard to follow request data integration flow. This used to take an IsomorphicRequest and then did a bunch of conversion etc.

Since now in Node, we always have the same, proper http request (for any framework, because this always goes through http instrumentation), we can actually streamline this and normalize this properly at the time where we set this.

So with this PR, we set a normalizedRequest which already has the url, headers etc. set in a way that we need it/it makes sense. Additionally, the parsed & stringified request body will be set on this too.

If this normalized request is set in sdkProcessingMetadata, we will use it as source of truth instead of the plain request. (Note that we still need the plain request for some auxiliary data that is non-standard, e.g. request.user).

For the body parsing itself, we monkey-patch req.on('data'). this way, we ensure to not add more handlers than a user has, and we only extract the body if the user is extracting it anyhow, ensuring we do not alter behavior.

Closes https://github.com/getsentry/sentry-javascript/issues/13722

mydea avatar Sep 23 '24 08:09 mydea

size-limit report 📦

⚠️ Warning: Base artifact is not the latest one, because the latest workflow run is not done yet. This may lead to incorrect results. Try to re-run all tests to get up to date results.

Path Size % Change Change
@sentry/browser 22.77 KB - -
@sentry/browser - with treeshaking flags 21.53 KB - -
@sentry/browser (incl. Tracing) 35.26 KB - -
@sentry/browser (incl. Tracing, Replay) 71.98 KB - -
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags 62.35 KB - -
@sentry/browser (incl. Tracing, Replay with Canvas) 76.31 KB - -
@sentry/browser (incl. Tracing, Replay, Feedback) 89.14 KB - -
@sentry/browser (incl. Feedback) 39.93 KB - -
@sentry/browser (incl. sendFeedback) 27.42 KB - -
@sentry/browser (incl. FeedbackAsync) 32.23 KB - -
@sentry/react 25.52 KB - -
@sentry/react (incl. Tracing) 38.22 KB - -
@sentry/vue 26.91 KB - -
@sentry/vue (incl. Tracing) 37.1 KB - -
@sentry/svelte 22.91 KB - -
CDN Bundle 24.13 KB - -
CDN Bundle (incl. Tracing) 37.04 KB - -
CDN Bundle (incl. Tracing, Replay) 71.7 KB - -
CDN Bundle (incl. Tracing, Replay, Feedback) 77.05 KB - -
CDN Bundle - uncompressed 70.73 KB - -
CDN Bundle (incl. Tracing) - uncompressed 109.9 KB - -
CDN Bundle (incl. Tracing, Replay) - uncompressed 222.42 KB - -
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed 235.64 KB - -
@sentry/nextjs (client) 38.33 KB - -
@sentry/sveltekit (client) 35.84 KB - -
@sentry/node 134.28 KB +0.59% +798 B 🔺
@sentry/node - without tracing 96.46 KB +0.83% +807 B 🔺
@sentry/aws-serverless 106.72 KB +0.74% +802 B 🔺

View base workflow run

github-actions[bot] avatar Sep 23 '24 08:09 github-actions[bot]

:x: 1 Tests Failed:

Tests completed Failed Passed Skipped
637 1 636 33
View the top 1 failed tests by shortest run time
transactions.test.ts Captures request metadata
Stack Traces | 0.034s run time
transactions.test.ts:139:5 Captures request metadata

To view individual test run time comparison to the main branch, go to the Test Analytics Dashboard

codecov[bot] avatar Sep 23 '24 08:09 codecov[bot]

🥹

maximedupre avatar Oct 04 '24 19:10 maximedupre