You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Redux Toolkit中无法捕获Firebase重复注册错误问题

问题分析与解决方案

核心问题

你当前无法捕获重复注册错误的原因有两个:

  1. dispatch(signUp(...)) 返回的是Redux Toolkit封装后的Promise,直接用try/catch无法捕获内部抛出的错误,需要额外处理才能提取真实错误信息。
  2. 代码里的response.json()没有加await,会导致返回Promise而非实际数据,影响后续状态处理。

解决步骤

1. 修复异步Thunk的数据获取逻辑

先修正signUp thunk中的数据解析,同时建议从Firebase返回的响应中提取具体错误信息,替代通用提示:

export const signUp = createAsyncThunk('signUp', async (user) => {
  const { email, password } = user
   
  const response = await fetch('https://identitytoolkit.googleapis.com/v1/accounts:signUp?key=<KEY VALUE REDACTED>', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ email, password, returnSecureToken: true }) // 必须添加该参数才能获取用户token
  });

  if (!response.ok) {
    // 提取Firebase返回的具体错误信息
    const errorData = await response.json();
    throw new Error(errorData.error.message || "Nous avons un problème lors de l'inscription");
  }
    
  const data = await response.json() // 添加await确保获取实际数据
  return data 
})

2. 方式一:在组件中用unwrapResult捕获错误

从@reduxjs/toolkit导入unwrapResult,通过它提取thunk内部的错误:

import { unwrapResult } from '@reduxjs/toolkit';

const handleSubmit = async () => {
  if (email.length > 0 && password.length > 0) {
    if (isSignUp) {
      setError(null)
      try {
        const result = await dispatch(signUp({ email, password }));
        unwrapResult(result); // 此处会抛出thunk中产生的错误
        // 注册成功后的逻辑,比如页面跳转
      } catch (error) {
        console.log(error.message);
        setError(error.message); // 将错误信息展示给用户
      }
    } else {
      // 登录逻辑
    }
  } 
}

3. 方式二:在Slice中管理错误状态(推荐)

在对应的slice中处理signUp.rejected动作,将错误信息存入state,组件通过useSelector读取:

示例Slice代码:

import { createSlice } from '@reduxjs/toolkit';
import { signUp } from './path-to-your-thunk';

const authSlice = createSlice({
  name: 'auth',
  initialState: {
    user: null,
    error: null,
    loading: false
  },
  reducers: {},
  extraReducers: (builder) => {
    builder
      .addCase(signUp.pending, (state) => {
        state.loading = true;
        state.error = null;
      })
      .addCase(signUp.fulfilled, (state, action) => {
        state.loading = false;
        state.user = action.payload;
      })
      .addCase(signUp.rejected, (state, action) => {
        state.loading = false;
        state.error = action.error.message; // 把错误信息存入状态
      });
  }
});

export default authSlice.reducer;

组件中读取并展示错误:

import { useSelector } from 'react-redux';

const YourComponent = () => {
  const { error: authError } = useSelector(state => state.auth);
  // ...其他组件逻辑

  const handleSubmit = async () => {
    if (email.length > 0 && password.length > 0) {
      if (isSignUp) {
        dispatch(signUp({ email, password }));
      } else {
        // 登录逻辑
      }
    } 
  };

  return (
    // ...组件其他内容
    {authError && <div className="error-message">{authError}</div>}
    // ...
  );
};

原代码try/catch无效的原因

Redux Toolkit的createAsyncThunk会自动捕获thunk内部的错误,将其封装为rejected动作。直接await dispatch(signUp(...))得到的是始终resolved的Promise,包含action对象而非错误,因此try/catch无法触发。必须通过unwrapResult提取错误,或通过slice的rejected状态管理来获取错误信息。

内容的提问来源于stack exchange,提问作者Papa Assane DIOP

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 19:58:36