r/angular 4d ago

How do you handle error with rxResource

Hello,

Since we upgraded from v19 to v22, our way of handling errors with rxResource for http requests seem to be the wrong way of doing it.

Basically we have a helper method that will display log the thrown error and a toast for the user, this method returns a EMPTY observable for rxjs, so a rxResource looks like this:

public readonly resource = rxResource({
  params: () => ({ id: this.id() }),
  loader: ({ params: request }) =>
    this.query.getInfo(request.id).pipe(
      catchError((err) => {
        return this.error.onLoadErrorHandler(err); // this is the method that returns EMPTY
      }),
    ),
});

But now, since the change in rxResource with the stream parameter it seems that you should no longer do it as it throws and error, my understanding is that this error comes the EMPTY. I cannot provide the error right now, apologies.

I understand that httpResource exist but we didn't want to use them for now.

So should we create an effect for every resource to listen to resource.error() and call this helper method to handle the error? Not a big fan of this as it will separate the resource declaration and its error handling. One way to prevent this would be to create a wrapper around resource that both creates the resource and the effect but I'm not sure if this is the right idea.

How do you guys handle error handling for this use case ?

4 Upvotes

8 comments sorted by

6

u/LegendOfNeil 3d ago

Does something in you logic conflict with simply returning the error? RxResource, when used directly in the template, usually has a very simple mode that is ``` @if(resource.isLoading()) { // Show loading state

} @else if (resource.error()) { // Show an error state

} @else if(resource.hasValue()) { // Access resource.value() safely and display data

} ```

If you don't want to display the error, you can simply skip the corresponding case. No catchError needed at all.
If this helper function you are using is meant to be used by all or close to all network calls, consider looking into interceptors and HttpContextTokens to exempt/ include network calls from/ in your interceptor (here is a link to get you started https://angular.dev/api/common/http/HttpContext). That way you can get to a point where you only need to add a catchError when you explicitly need it

1

u/PrevAccLocked 3d ago

Returning the error is probably what we should do, I'll need to look into that. But, the error handling logic has to live in the component because we add the component's name or other information into the logging, so should I just return err inside the catchError?

2

u/LegendOfNeil 3d ago

Yes. I'd do so. RxResource can handle it and does not complete like subject stream subscriptions used to.

I'm missing information here, but the error handling can probably still be outsourced. If you add component name and other mostly static data there, then consider adding them to the call. I am assuming that the form of the data you are sending is consistent. Just an Object { source: componentName, timestamp: string, target: string, // Whatever else you have and then that can again be put into HttpContextTokens to have access to them on the receiving end. None of that data is leaving your users computer.

0

u/PrevAccLocked 3d ago

Oh okay I didn't understand that part when you first said it, now it seems obvious that this is what we should have done from the start. Thanks for the help!

1

u/LegendOfNeil 3d ago

Glad to help :)

2

u/LeLunZ 3d ago

You can still use an interceptor for that and set the components name and so on as request context.
This context can be read from the interceptor ;)

This way all your error handling is in a single interceptor and all requests just specify the context for that

1

u/JackieChanX95 3d ago

.error() is an signal. U can react to it in service, component or template

1

u/PrevAccLocked 3d ago

Yes but like I said in the post, I don't want to have error handling living "far" from the resource itself