问题描述
我已经开始实现我的身份验证服务,它在后面使用 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();
}
显然,它更喜欢在操作中捕获异常,并用它更新状态。