Redux error handling in Angular with ngrx and ngrx/effects

using ErrorEffects with ngrx/effects to keeping your components clean.

with ngrx/effects you can nicely work with side effects in your application like fetching something from a remote origin over http etc. but how can we deal with errors cases in a nice way without putting all of the error handling code into the component.

You may want to show some nice error messages using material.angular/snack-bar to the user, indicating that something went wrong.

Especially if you have multiple effects like a list-effect and a detail-effect that fetch data from the backend you may want to deal with all of the error cases in a general way.


The fetch happy case flow:

  1. in component dispatch LoadList or LoadDetail action.
  2. in reducer set isLoading state true on both of the actions.
    (so you can show a loading indicator in the component UI)
  3. in effects the loadDetail$ (or loadList$)-effect can take care of calling myHttpService to fetch by matching for your actions.
  4. in effects remap the success observable response to an LoadListSuccess or LoadDetailSuccess.
  5. in reducer set isLoading state false on both actions and set the payload to your state show the result in the ui component.

The fetch error case flow:

So how can we handle error cases of LoadList or LoadDetail in a nice way without bloating our component or even myHttpService?

=> with ErrorActions !

By making use of pipe and catchError from rxjs/operators we can remap both (or all) error cases into a single ErrorAction, that we can then handle directly in the effects and do side effect ui changes.

Here is how the full flow would look like:

  1. in component dispatch LoadList or LoadDetail action.
  2. in reducer set isLoading state true on both of the actions.
  3. in effects the loadDetail$ (or loadList$)-effect can take care of calling myHttpService to fetch by matching for your actions.
  4. in effects remap error payloads into a LoadError action by piping the errors using the catchError operator.
  5. in reducer set isLoading state false on LoadError actions. 
    (to hide the loading indicator, so it does not hang for ever)
  6. in effects handle LoadError actions with onLoadError$ -effect showing some nice error message using the snackBar (provided by material.angular/snack-bar for example). 
    Here you can put additional code to handle different kinds of responses like 404 different from 401. For a 401 you might want to dispatch a ShowLoginFormaction as the user might got logged out for example. 
    Or you can just remap actions of type LoadError into a no-op action afterwards, so no state impact is taken in your reducer.

Code example in typescript:

Like this you can keep the error handling code out of you components, what i thing is pretty nice. The best thing about it, it’s really easy to write tests for this, unit and end2end.

cheers and happy error handling!