Skip to content

feat(react-router): Support renderToReadableStream in createSentryHandleRequest - #25254

Draft
lfantone wants to merge 2 commits into
getsentry:developfrom
lfantone:feat/react-router-web-stream-handle-request
Draft

lfantone wants to merge 2 commits into
getsentry:developfrom
lfantone:feat/react-router-web-stream-handle-request

Conversation

@lfantone

Copy link
Copy Markdown

Adds a Web Streams variant of createSentryHandleRequest, so apps on renderToReadableStream (non-Node runtimes, or Node with unstable_enableNodeReadableStream) no longer have to hand-compose wrapSentryHandleRequest and injectTraceMetaTags.

Following the constraints from the discussion on the issue to keep it non-breaking:

  • SentryHandleRequestOptions and the Node path are untouched. The Web options are a separate type, accepted through an overload and only used when renderToReadableStream is passed in.
  • The Web handler lives in its own module with no Node imports, and is exported from the cloudflare entry as well as the server entry. Otherwise it would only help Node apps. No new runtime imports or peer dependencies.
  • A </head> split across chunks was previously missed by both transformers. A shared helper now holds back only a trailing partial </head> (rather than a fixed number of characters) and flushes it at the end of the stream, so it adds as little streaming delay as possible. It is used by getMetaTagTransformer (Node) and injectTraceMetaTags (Web).
  • injectTraceMetaTags moved to a Node-free module and is still re-exported from /cloudflare, so the public API is unchanged.
  • The react-router-8-framework cloudflare e2e entry now uses the new API instead of a hand-written copy of it.

Fixes #25168

…dleRequest

Adds a Web Streams variant of createSentryHandleRequest, accepted through an overload and exported from the cloudflare entry, and handles a </head> tag split across chunks in both the Node and Web transformers.

Closes getsentry#25168

@chargome chargome left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Overall looks good already, will trigger ci

body.allReady.then(clearAbortTimer, clearAbortTimer);

if (isBot || isSpaMode) {
await body.allReady.catch(() => undefined);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is this catch intended? If so why?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Not intentional, removed. It would have hidden fatal allReady errors and sent bots/SPA a 200 with a broken body. It now rejects like a shell error does. Added a test.

Comment on lines +7 to +11
import type {
HandleRequestWithMiddleware,
HandleRequestWithoutMiddleware,
SentryWebStreamHandleRequestOptions,
} from './createSentryHandleRequestWebStream';

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

These imports should move to some shared type file instead. Node should not import from the web types

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Moved to handleRequestTypes.ts, so Node now only imports types from there. It still imports the Web handler at runtime for the dispatch.

…types

Resolve the trace meta tags when injectTraceMetaTags is called instead of inside the stream transform. Runtimes such as workerd run the transform outside the request's async context, where no trace data is available, so the tags were silently dropped.

Also let allReady rejections propagate for bots and SPA mode, and move the handler types shared by the Node and Web Streams handlers into their own module.
@lfantone

Copy link
Copy Markdown
Author

The hydrogen e2e failure was a regression from this PR: the trace tags were resolved inside the stream transform, which workerd runs outside the request context. They're now resolved up front. Fixed in 424465d.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

external PR from an external contributor

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(react-router): support renderToReadableStream in createSentryHandleRequest

2 participants