Replies: 4 comments 7 replies
-
This would resolve a lot of errors and poor user experience in our app. As @sergiodxa mentioned we could use localStorage to save form state, but that gets very cumbersome in an app of our size (700 routes). In some things, like background logging, we've had to go back to just using plain Alternatively, something like an |
Beta Was this translation helpful? Give feedback.
-
See my comment over here #7634 (comment) I'm thinking clientLoader and clientAction might provide a clean solution to this. To handle the general case, maybe need clientMiddleware??? 🤔 If you wanted to handle all network error in your app the same, it would be a shame to have repeat your clientAction in every file... |
Beta Was this translation helpful? Give feedback.
-
This is really relevant for me right now. My API returns a 500 or 400 and I just wanna display that in a modal, without the ErrorBoundary blowing away the page, so that the user can close the modal, make some adjustments and try again. |
Beta Was this translation helpful? Give feedback.
-
My biggest issue with an approach like this is that Components today are happy path - i.e., you are guaranteed that export default function Component() {
let data = useLoaderData();
let networkError = useNetworkError();
if (networkError) {
// unhappy path
} else if (data) {
// happy path
}
} I think this API is somewhat less concerning for fetchers since they are already conditional on having data by default. I don't know that I'd want to introduce another let fetcher = useFetcher();
// If you specify bubbleErrors: false, then it's on you to branch accordingly
fetcher.load('/', { treatErrorsAsData: true })
if (!fetcher.data) {
// fetcher is idle/loading
} else if (isNetworkError(fetcher.data)) {
// never reached the loader
} else if (isRouteErrorResponse(fetcher.data)) {
// loader throw a Response
} else if (fetcher.data instanceof Error) {
// loader threw and Error
} else {
// loader returned data
} A few related proposals:
Also worth noting that once client data lands, you'll be able to do this manually on a per-route basis by converting your errors to data (this would apply to both fetchers and navigational loaders/actions): async function clientLoader({ serverLoader }) {
try {
let res = await serverLoader();
return res;
} catch (e) {
// catch network errors and return them as data
return { ok: false, error: e }
}
} |
Beta Was this translation helpful? Give feedback.
-
Proposal
Add a way to handle network errors from within the Remix app.
Background
Right now, if there's a network error while Remix does a request to the server there's no way to handle it. This is a problem because if the user has any connectivity issue the app will fail, this is even worst in the case of actions where the form UI will be replaced by the nearest ErrorBoundary and the user will lose any change, unless of course the app saves them to localStorage.
This is based on a conversation here #5957 (comment).
Use Case
API/Examples
Handle lack of connectivity
With the
useNetworkStatus
hook applications should be able to handle lack of connectivity and prevent submissions.The hook will return a
NetworkStatus
interface.This can be used to disable a button if it's offline:
Or to prevent form submissions and maybe warn the user.
Handle global network errors (Form/useSubmit)
If we don't prevent the submission at all, the request may fail, the
useNetworkError
hook should let use get the error and handle it.Then we can use it to show a toast or something.
We could also save the user data
Or you could retry the submission:
And because you have access to the Error object you can also throw it to the ErrorBoundary if you prefer.
Handle network errors in Fetchers
Since fetchers can be sent in parallel, each fetcher should come with its own network error object.
Beta Was this translation helpful? Give feedback.
All reactions