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

RTK Query钩子处理400错误:error与status返回undefined

处理RTK Query中400状态码错误的解决方案

核心问题分析

你遇到的error和status未定义、try/catch无效的问题,主要是因为RTK Query的mutation默认不会将错误状态的请求直接抛出异常,且你可能未正确使用钩子返回的异步方法。结合JSON-server的场景,以下是具体解决步骤:


步骤1:配置Auth API Slice的错误处理

首先在authApi.ts中,确保mutation正确识别400状态码,并格式化错误响应:

import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';

export const authApi = createApi({
  reducerPath: 'authApi',
  baseQuery: fetchBaseQuery({ baseUrl: '/api' }),
  endpoints: (builder) => ({
    loginUser: builder.mutation({
      query: (credentials) => ({
        url: '/login',
        method: 'POST',
        body: credentials,
        // 保留默认的状态码校验:仅2xx视为成功,其余为错误
        // validateStatus: (status) => status >= 200 && status < 300,
      }),
      // 格式化错误响应,方便后续获取状态码和提示信息
      transformErrorResponse: (response) => {
        return {
          status: response.status,
          message: response.data?.message || '登录失败'
        };
      }
    })
  })
});

export const { useLoginUserMutation } = authApi;

步骤2:正确使用Mutation钩子捕获错误

在登录组件中,必须调用.unwrap()方法将RTK Query的包装Promise转为普通Promise,这样try/catch才能捕获到400等错误状态:

import { useLoginUserMutation } from './authApi';

function LoginForm() {
  const [loginUser, { error, status }] = useLoginUserMutation();

  const handleSubmit = async (e) => {
    e.preventDefault();
    const credentials = {
      username: e.target.username.value,
      password: e.target.password.value
    };

    try {
      // 调用unwrap(),让错误状态的请求抛出异常
      const loginResult = await loginUser(credentials).unwrap();
      // 登录成功逻辑
      console.log('登录成功:', loginResult);
    } catch (err) {
      // 捕获到400等错误
      console.log('登录错误:', err.status, err.message);
      if (err.status === 400) {
        alert('用户不存在或密码错误');
      }
    }
  };

  // 也可通过监听钩子返回的状态变化处理错误
  // useEffect(() => {
  //   if (status === 'rejected' && error) {
  //     if (error.status === 400) {
  //       alert('用户不存在');
  //     }
  //   }
  // }, [status, error]);

  return (
    <form onSubmit={handleSubmit}>
      <input name="username" placeholder="用户名" />
      <input name="password" type="password" placeholder="密码" />
      <button type="submit">登录</button>
    </form>
  );
}

步骤3:确保JSON-server返回合法JSON响应

检查你的JSON-server自定义路由,确保400状态码返回的是JSON格式,而非纯文本:

// 示例:自定义server.js中的登录路由
const jsonServer = require('json-server');
const server = jsonServer.create();
const router = jsonServer.router('db.json');
const middlewares = jsonServer.defaults();

server.use(middlewares);
server.use(jsonServer.bodyParser);

server.post('/login', (req, res) => {
  const { username, password } = req.body;
  const users = router.db.get('users').value();
  const matchedUser = users.find(u => u.username === username && u.password === password);

  if (matchedUser) {
    res.status(200).json({ token: 'fake-auth-token', user: matchedUser });
  } else {
    // 必须返回JSON格式的错误响应
    res.status(400).json({ message: 'cannot find user' });
  }
});

server.use(router);
server.listen(3000, () => {
  console.log('JSON Server is running');
});

内容的提问来源于stack exchange,提问作者Hez

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 02:46:09