哪里/如何捕获 NGXS 操作中发生的异常?

问题描述

我有一个 Ionic 应用,它使用 NGXS 来存储状态。

我已经开始实现我的身份验证服务,它在后面使用 firebase(使用 angularfire)。

所以,基本上,我有这个动作:

  @Action(LoginWithPasswordAction)
  async loginWithPassword(ctx: StateContext<AuthStateModel>,action: LoginWithPasswordAction) {
    
      const result = await this.angularFireAuth.signInWithEmailAndPassword(action.email,action.password);
      await this.router.navigate(['/']);
    
  }

ngxsOnInit 中,我注册到 angularFire 的 authState 的更改以更新状态:

  ngxsOnInit(ctx?: StateContext<any>) {
    this.profileSubscription = this.angularFireAuth.authState
      .pipe<Profile>(
        switchMap<User,Observable<Profile>>((user) => {
          if (user) {
            return this.angularFireStore.doc<Profile>(`users/${user.uid}`).valueChanges();
          } else {
            return of(null);
          }
        })
      )
      .subscribe((profile) => {
        const formatedProfile = profile ? this.formatFromFirebase(profile) : null;
        ctx.patchState({
          profile: formatedProfile,loaded: profile !== null          
        });
      });
  }

当我登录成功时,这个工作完美。

现在,我必须处理错误情况。目前,如果我使用错误的密码,firebase 会抛出异常。

我有点希望能够在我的登录组件中在我发送操作的地方“捕获”它:

  async login() {
    if (this.loginForm.valid) {
      try {
        await this.store.dispatch(
          new LoginWithPasswordAction(this.loginForm.get('email').value,this.loginForm.get('password').value)
        );
        this.navController.navigateRoot('/');
      } catch (ex) {
        console.log(ex)
        this.loginError = ex.message;
      }
    }
  }

但我没有收到异常,我猜是因为 NGXS 为我捕获了它(在日志中,我看到错误来自 NGXS-logger-plugin)

所以: 在NGXS概念中,应该在哪里/如何捕获/处理动作中发生的异常?

解决方法

我想我找到了答案。

根据文档显然有两种捕获异常的方法(我的不好):https://www.ngxs.io/advanced/errors

在行动中

  @Action(HandledError)
  handledError(ctx: StateContext<StateModel>) {
    try {
      // error is thrown
    } catch (err) {
      console.log('error catched inside @Action wont propagate to ErrorHandler or dispatch subscription')
    }
  }

或您在何处发送操作:

  @Action(UnhandledError)
  unhandledError(ctx: StateContext<StateModel>) {
    // error is thrown,DO NOT CATCH IT
  }



  unhandled() {
    this.store.dispatch(new UnhandledError()).pipe(
      catchError(err => {
        console.log('unhandled error on dispatch subscription')
        return of('')
      })
    ).subscribe();
  }

显然,它更喜欢在操作中捕获异常,并用它更新状态。