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

[Docs]: It is unclear how to return errors from server-side Resource Routes #12888

Open
apike opened this issue Jan 29, 2025 · 2 comments
Open
Labels

Comments

@apike
Copy link

apike commented Jan 29, 2025

Describe what's incorrect/missing in the documentation

The doc for Resource Routes encourages you to return a Response.json from a REST/resource endpoint, but only shows the happy path.

If you return a Response.json with { status: 500 }, it sort of works but error reporting doesn't work – that is, the central handleError in entry.server.tsx doesn't fire.

This, plus the fact Remix tended towards having you throw errors, makes it seem like you are not supposed to return an error from a resource route.

However, the Error Boundaries doc says:

It's not recommended to intentionally throw errors to force the error boundary to render as a means of control flow. ... This is not just for loaders, but for all route module APIs: loaders, actions, components, headers, links, and meta.

And the Status Codes doc advises you to "Set status codes from loaders and actions with data.", with this example returning a 4xx error inside an action:

    return data(
      { message: "Invalid title" },
      { status: 400 }
    );

These make it seem like you are supposed to return an error, but meanwhile, there's also similar but different format in the Error Boundaries doc showing a throw under the title Throw data in loaders/actions:

    throw data("Record Not Found", { status: 404 });

Since the above is in the Error Boundaries doc, it's not clear this is applicable to resource routes, since I believe resource routes do not render within an Error Boundary.

So, in short, can we get clear & consistent documentation on how we're meant to return a 4xx or 5xx error from an resource route's action?

@apike apike added the docs label Jan 29, 2025
@apike
Copy link
Author

apike commented Feb 3, 2025

I'm up for doing a PR to update the docs for this, I just need a little direction from somebody closer to the project on what the recommended pattern here is, then I can write it up.

@apike
Copy link
Author

apike commented Feb 3, 2025

I see now that the Remix dev docs have more to say on these topics, even though they are not fully updated for the new conventions of React Router 7. I've got a bit more insight from them below.

In entry.server it says:

Thrown Responses

Note that this does not handle thrown Response instances from your loader/action functions. The intention of this handler is to find bugs in your code which result in unexpected thrown errors. If you are detecting a scenario and throwing a 401/404/etc. Response in your loader/action then it's an expected flow that is handled by your code. If you also wish to log, or send those to an external service, that should be done at the time you throw the response.

Some other breadcrumbs from the Remix dev docs:

  • some documention for the data helper, which show the pattern of returning a 4xx error
  • The Remix dev doc on error handling, which shows throwing a 500 Response.

So it seems that:

  • 500s are always meant to be thrown and never returned
  • 3xx and 4xx codes are sometimes meant to be thrown and sometimes returned
  • 2xx are always meant to be returned
  • data only needs to be used if you're setting headers or a non-500 error code, otherwise you're meant to throw/return a plain object
  • The first parameter to data is just whatever you want to send to the client – there seems to be nothing special about message vs passing in a plain string, other than that to log and reason about your errors on the other side, you probably want all your error throw/returns to have the same structure.

Unfortunately, I haven't been able to crack what the hueristic is for when should you throw a 3xx or 4xx, vs. when to return one, in the context of an action. If somebody can point me to the answer to that, I think I could put together a docs PR that clarifies this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant