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
相关产品推荐
相关产品推荐

