如何让React Toastify展示后端自定义登录错误?
解决React Toastify无法显示后端自定义错误的问题
问题说明
使用MongoDB开发登录功能,已集成react-toastify组件展示后端错误信息,但目前仅能显示普通提示,无法正确渲染后端自定义错误,前端控制台打印err.response.data.error显示undefined。
前端调用Toast的代码
const handleSubmit = async (e) => { e.preventDefault(); try { const { data } = await axios.post(process.env.REACT_APP_LOGIN, { username, password }); if (data.success === true) { setValues({ username: '', password: '' }); toast.success("Sign in successfully"); // 保存用户到本地存储 if (typeof window !== "undefined") { localStorage.setItem("token", JSON.stringify(data)); } navigate("/map"); } } catch (err) { // 日志输出undefined console.log(`This is the error: ${err.response.data.error}`); toast.error(`There is an error: ${err.response.data.error}`); } } return ( <div className='loginContainer'> <div className='logo'></div> <AddLocationAltIcon/> Pin <form className='loginForm'> <input type='text' className='usernameE' placeholder='username' onChange={handleChange('username')}/> <input type='password' className='passwordE' placeholder='password' onChange={handleChange('password')} /> <button className='loginBtn' onClick={handleSubmit} type="submit">Login</button> <button onClick={() => navigate('/register')} className="loginRegister"> Sign Up </button> </form> </div> )
后端登录接口代码
exports.signin = async (req, res, next)=> { try { const { username, password } = req.body; // 检查用户名和密码是否存在 if (!username || !password) { return next(new ErrorResponse(`Username and password are required`, 404)) } // 检查用户名是否存在 const user = await User.findOne({ username }); if (!user) { return next(new ErrorResponse(`Invalid credentials`, 404)) } // 验证密码是否匹配 const isMatched = await user.comparePassword(password); if (!isMatched) { return next(new ErrorResponse(`Cannot log in, check your credentials`, 404)) } generateToken(user, 200, res); } catch (error) { console.log(error); return next(new ErrorResponse(`Cannot log in, check your credentials`, 404)) } }
ErrorResponse自定义错误类
class ErrorResponse extends Error { constructor(message, statusCode) { super(message); this.statusCode = statusCode; } } module.exports = ErrorResponse;
解决方案
1. 补充后端错误处理中间件
后端需要添加全局错误处理中间件,将ErrorResponse的消息和状态码格式化后返回给前端,确保响应包含error字段:
// 全局错误处理中间件 app.use((err, req, res, next) => { // 默认状态码500,默认错误消息 const statusCode = err.statusCode || 500; const errorMessage = err.message || 'Server Error'; // 返回符合前端预期的JSON结构 res.status(statusCode).json({ success: false, error: errorMessage }); });
注:如果已有错误中间件,需确保返回的JSON结构包含
error字段,对应前端读取的err.response.data.error。
2. 优化前端错误处理逻辑
在catch块中增加容错处理,避免因err.response不存在(如网络错误)导致的报错,同时确保正确读取错误消息:
catch (err) { // 使用可选链操作符安全访问嵌套属性 const errorMsg = err.response?.data?.error || '登录失败,请稍后重试'; console.log(`错误信息: ${errorMsg}`); toast.error(`登录错误: ${errorMsg}`); }
3. 验证后端响应格式
打开浏览器开发者工具的Network标签,触发登录错误请求,查看响应的JSON内容,确认是否包含error字段且值为自定义错误消息。若格式不符,调整后端错误中间件的返回结构。
内容的提问来源于stack exchange,提问作者Bqdor
相关产品推荐
相关产品推荐

