question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

makeWrappedRootLoader does not handle Response cases

See original GitHub issue

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.9.0

Framework Version

React 17.0.2

Link to Sentry event

No response

Steps to Reproduce

  1. Create a Remix project with a root loader that returns a response object (or uses the Remix provided json function).
export const loader: LoaderFunction = async () => {
  return json(
    { data_one: [], data_two: "a string" },
    { headers: { 'Cache-Control': 'max-age=300' } }
  )
}
  1. Configure Sentry via Sentry.init(...) in entry.server.tsx
  2. Load the root page in a browser
  3. Inspect __remixContext.routeData.root in dev tools and it will have the shape { sentryBaggage: string, sentryTrace: string, size: number } instead of containing the loader data.

This looks to be caused by the makeWrappedRootLoader function which handles the result of the origLoader as an Promise<AppData> | AppData instead of Promise<Response> | Response | Promise<AppData> | AppData:

function makeWrappedRootLoader(origLoader: DataFunction): DataFunction {
  return async function (this: unknown, args: DataFunctionArgs): Promise<Response | AppData> {
    const res = await origLoader.call(this, args);

    return { ...res, ...getTraceAndBaggage() };
  };
}

Expected Result

Data and ResponseInit settings are propagated when a Promise<Response> or Response is returned from the root loader.

Actual Result

Data and headers (or ResponseInit) data from the root loader are omitted from data on the client and the response respectively.

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

3reactions
augustuswmcommented, Aug 10, 2022

Thanks for getting a fix for this. One note, looking at the PR, is that Remix allows for user defined headers to be included in the Response that is returned from a loader. Currently by transforming the Response into a plain object these settings are lost. The current fix makes sense to unblock anyone that is immediately stuck, but a more complete fix probably looks something like:

function makeWrappedRootLoader(origLoader: DataFunction): DataFunction {
  return async function (this: unknown, args: DataFunctionArgs): Promise<Response | AppData> {
    const res = await origLoader.call(this, args);
    const traceAndBaggage = getTraceAndBaggage();

    // Note: `redirect` and `catch` responses do not have bodies to extract
    if (isResponse(res) && !isRedirectResponse(res) && !isCatchResponse(res)) {
      const data = await extractData(res);

      if (typeof data === 'object') {

        // A new response needs to be constructed as the original body can not be replaced
        return new Response(
          JSON.stringify({ ...data, ...traceAndBaggage }),
          { status: res.status, statusText: res.statusText, headers: res.headers }
        );
      } else {
        __DEBUG_BUILD__ && logger.warn('Skipping injection of trace and baggage as the response body is not an object');
        // Return the response as-is without any changes
        return res;
      }
    }

    return { ...res, ...traceAndBaggage };
  };
}
1reaction
AbhiPrasadcommented, Aug 10, 2022

Hey folks, fix should be released with https://github.com/getsentry/sentry-javascript/releases/tag/7.10.0! Thanks for your patience.

Read more comments on GitHub >

github_iconTop Results From Across the Web

HTTP response status codes - MDN Web Docs - Mozilla
HTTP response status codes indicate whether a specific HTTP request has been successfully completed. Responses are grouped in five classes:
Read more >
HTTP/1.1: Status Code Definitions
The 202 response is intentionally non-committal. Its purpose is to allow a server to accept a request for some other process (perhaps a...
Read more >
What could happen if I don't close response.Body?
It is the caller's responsibility to close Body. So there is no finalizers bound to the object and it must be closed explicitly....
Read more >
A Guide to HTTP Status Codes - Siteimprove Support
HTTP Response Codes indicate whether specific HTTP requests have been successfully completed. It's an indicator of whether a web page has ...
Read more >
Response handling examples | IntelliJ IDEA Documentation
In this topic, we'll examine a couple of HTTP response handling examples. ... client.assert(response.status === 200, "Response status is not ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found