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

Remix: Throwing a 4XX/5XX Response causes a "body already used for" error #5423

Closed
3 tasks done
dmarkow opened this issue Jul 15, 2022 · 2 comments · Fixed by #5429
Closed
3 tasks done

Remix: Throwing a 4XX/5XX Response causes a "body already used for" error #5423

dmarkow opened this issue Jul 15, 2022 · 2 comments · Fixed by #5429

Comments

@dmarkow
Copy link

dmarkow commented Jul 15, 2022

Is there an existing issue for this?

How do you use Sentry?

Sentry Saas (sentry.io)

Which package are you using?

@sentry/remix

SDK Version

7.7.0

Framework Version

7.7.0

Link to Sentry event

No response

Steps to Reproduce

Remix lets you throw responses for things like a 404 Not Found:

export const loader = async () => {
  throw new Response("Not Found", { status: 404 });
};

You would then use a remix CatchBoundary to catch the 404 and display a message. To reproduce, just add the loader above to any route and try to open the page.

Expected Result

Sentry should pass the 404 through and allow the CatchBoundary to show it. It worked fine in 7.6.0.

Actual Result

As of 7.7.0, @sentry/remix is causing the following error when loading any page that throws a response. It only happens if the page was server rendered, e.g. given a route /foo that throws a 404, if I load /foo directly and it server renders, it crashes with the error below. If I load / first, then navigate client-side to /foo, it uses the catch boundary properly. I assume this is related to the updates in #5405 since it worked fine in 7.6.0 and that PR addressed some thrown responses.

TypeError: body used already for: 
    at consumeBody (/Users/dylan/dev/smp/node_modules/@remix-run/web-fetch/src/body.js:205:9)
    at NodeResponse.text (/Users/dylan/dev/smp/node_modules/@remix-run/web-fetch/src/body.js:171:24)
    at Object.extractData (/Users/dylan/dev/smp/node_modules/@remix-run/server-runtime/dist/data.js:138:19)
    at handleDocumentRequest (/Users/dylan/dev/smp/node_modules/@remix-run/server-runtime/dist/server.js:331:28)
    at requestHandler (/Users/dylan/dev/smp/node_modules/@remix-run/server-runtime/dist/server.js:49:18)
    at /Users/dylan/dev/smp/node_modules/@sentry/remix/cjs/utils/instrumentServer.js:167:16
    at /Users/dylan/dev/smp/node_modules/@remix-run/express/dist/server.js:39:22

It's just raw text from the server, not handled by any ErrorBoundary. If I throw a standard Error object instead, it uses the ErrorBoundary.

@alexblack
Copy link

I hit this too: #5425

@onurtemizkan
Copy link
Collaborator

Thanks for reporting this @dmarkow and @alexblack!

Opened a PR to fix it! #5429

lobsterkatie pushed a commit that referenced this issue Jul 21, 2022
…ms. (#5429)

Fixes: #5423

Ref: #5405 

We were extracting the bodies of 4xx/5xx responses to capture, but Remix also uses them, we should not consume their `body` streams, as they are only available once in response lifespans. 

This PR updates `extractData` to work on a clone response.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants