已捕获异常仍报Uncaught (in promise): FirebaseError问题排查
问题原因
你遇到的未捕获Promise错误来自auth.service.ts中**未被纳入主Promise链、也没有单独捕获错误的嵌套Promise:
你在signInWithEmailAndPassword的成功回调中调用了user.getIdToken(),这是一个独立异步方法,返回独立的Promise。你既没有将它return到外层的Promise链中,也没有给它添加单独的catch逻辑,一旦这个方法执行报错(比如网络波动、令牌生成失败等),错误无法被外层的catch捕获,就会直接抛出Uncaught (in promise)报错。
你现有的错误捕获逻辑只能覆盖signInWithEmailAndPassword本身的错误,完全覆盖不到这个嵌套异步操作的异常。
修复方案
步骤1:调整auth.service.ts的Promise链结构
将getIdToken的操作接入主Promise链,让外层的catch可以统一捕获所有环节的错误:
/** * 登录 * * @param credentials 登录凭证 */ signIn(credentials: { email: string; password: string }): Promise<any> { return this.auth.signInWithEmailAndPassword(credentials.email, credentials.password) .then((userCredential) => { // 登录成功,返回getIdToken的Promise接入主链 return userCredential.user.getIdToken(); }) .then(token => { // 存储令牌 this.accessToken = token; // 将已认证标志设置为true this._authenticated = true; // 其他用户信息存储逻辑 }) .catch((error) => { // 可捕获登录、令牌获取全链路的错误 const errorCode = error.code || error; console.log('展示错误', errorCode); throw errorCode; }); }
步骤2(可选优化):统一组件内的错误捕获写法
组件中可以用then+catch的写法替代then的双参数写法,逻辑更清晰,避免歧义:
/** * 登录 */ signIn(): void { // 表单校验不通过则直接返回 if ( this.signInForm.invalid ) { return; } // 禁用表单 this.signInForm.disable(); // 隐藏提示 this.showAlert = false; // 执行登录 this._authService.signIn(this.signInForm.value) .then(() => { // 设置重定向地址 const redirectURL = this._activatedRoute.snapshot.queryParamMap.get('redirectURL') || '/signed-in-redirect'; // 跳转到重定向地址 this._router.navigateByUrl(redirectURL); }) .catch((response) => { console.log('来自auth.service的错误', response); // 重新启用表单 this.signInForm.enable(); // 重置表单 this.signInNgForm.resetForm(); // 设置提示内容 this.alert = { type : 'error', message: '邮箱或密码错误' }; // 展示提示 this.showAlert = true; }); }
调整后所有异步操作的错误都会被统一捕获,不会再出现未捕获的Promise报错。
内容的提问来源于stack exchange,提问作者Luis Cabrera
相关产品推荐
相关产品推荐

