Shopify / hydrogen

Hydrogen lets you build faster headless storefronts in less time, on Shopify.
https://hydrogen.shop
MIT License
1.45k stars 280 forks source link

ErrorBoundary not rendering on account_.authorize.jsx #2644

Open AlvaroRocket opened 2 weeks ago

AlvaroRocket commented 2 weeks ago

What is the location of your example repository?

https://github.com/RocketROI/holafly-hydrogen (private repo)

Which package or tool is having this issue?

Hydrogen

What version of that package or tool are you using?

2024.10.0

What version of Remix are you using?

2.13.1

Steps to Reproduce

The issue is not so much that there is an error on login, that is something that can happends, but:

Our client tries to login using the Customer Account API. The email got stuck in its firewall and after allowing it and trying to login, it fires a Bad request: Unauthorized error.

Another way to reproduce it is to simply navigate to /account/authorize

Trying on with the based Hydrogen project from the cli I can also reproduce it without credentials, getting:

You do not have the valid credential to use Customer Account API (/account).

Expected Behavior

We should expect to render the ErrorBoundary component at root.jsx to display the user that something went wrong and give him the option to exercise some actions.

Image

Actual Behavior

Instead of the ErrorBoundary, we get:

We should be able to have some control over the route to at least redirect the user or displaying some information.

Image Image

wizardlyhel commented 4 days ago

That's interesting that the root error boundary doesn't catch this. We'll investigate further on this issue.

For now, you can capture the error a bit earlier by defining an ErrorBoundary in the routes/account_.authorize.tsx.

import { isRouteErrorResponse, useRouteError } from '@remix-run/react';
import type {LoaderFunctionArgs} from '@shopify/remix-oxygen';

export async function loader({context}: LoaderFunctionArgs) {
  return context.customerAccount.authorize();
}

export function ErrorBoundary() {
  const error = useRouteError();
  let errorMessage = 'Unknown error';
  let errorStatus = 500;

  if (isRouteErrorResponse(error)) {
    errorMessage = error?.data?.message ?? error.data;
    errorStatus = error.status;
  } else if (error instanceof Error) {
    errorMessage = error.message;
  }

  return (
    <div className="route-error">
      <h1>Oops</h1>
      <h2>{errorStatus}</h2>
      {errorMessage && (
        <fieldset>
          <pre>{errorMessage}</pre>
        </fieldset>
      )}
    </div>
  );
}