ngneat / effects

🪄 A framework-agnostic RxJS effects implementation
https://www.netbasal.com
MIT License
63 stars 11 forks source link

catchError in effects not working #63

Open jmeinlschmidt opened 1 year ago

jmeinlschmidt commented 1 year ago

Which @ngneat/effects-* package(s) are the source of the bug?

effects-ng

Is this a regression?

No

Description

Operator catchError in effects is not working and after throwing an error, the effect stops emitting. Please see full example in stackblitz.

public myEffect = this.createEffectFn(($: Observable<string>) =>
  $.pipe(
    tap((no) => console.log('effect invocation', no)),
    map(() => {
      throw new Error('error here');
    }),
    catchError((e) => {
      console.log('catched', e);
      return of();
    })
  )
);

This is related to https://github.com/ngneat/effects/discussions/34. I think this applies to effect functions as well, see createEffectFn implementation.

Please provide a link to a minimal reproduction of the bug

https://stackblitz.com/edit/stackblitz-starters-tvg994?file=src%2Fmain.ts

Please provide the exception or error you saw

No response

Please provide the environment you discovered this bug in

No response

Anything else?

No response

Do you want to create a pull request?

No

stackblitz[bot] commented 1 year ago

Fix this issue in StackBlitz Codeflow Start a new pull request in StackBlitz Codeflow.

dimi4e commented 8 months ago

I have the same issue, when try to make HTTP request

loadUsers$ = createEffect((actions) =>
        actions.pipe(
            ofType(loadUsers),
            switchMap(() => this.usersService.getAll()),
            catchError((err) => { notifyAboutError(err); return NEVER; }),
            tap(setUserList)
        )
    );

After an error occurs, the effect stops. One possible solution is to refrain from catching errors within the action pipe and instead catch them in the HTTP response stream, as illustrated below:

loadUsers$ = createEffect((actions) =>
        actions.pipe(
            ofType(loadUsers),
            switchMap(() => this.usersService.getAll().pipe(catchError(() => {
                 notifyAboutError(err);
                 return of(null);
            }))),
            tap((result) => {
                if (!result) return;
                setUserList(result);
            })
        )
    );