Vue2前端无法捕获Lua后端返回的自定义错误信息,反而出现TypeError异常
看起来你遇到了前后端错误处理衔接的典型问题——明明后端已经返回了正确的401状态码和自定义错误信息,前端不仅拿不到内容,还在catch块里触发了TypeError。我来帮你一步步排查解决:
一、先搞定前端catch块的TypeError问题
你提到错误触发在console.log(error.toString())这行,这说明error对象的结构和你预期的Error实例不一样。Axios的错误对象有特定的结构,直接调用toString()很容易出问题,先把错误内容打全再说。
修改catch块代码,先打印完整错误对象,再针对性处理:
.catch((error) => { // 先打印完整错误,明确真实结构 console.log('完整错误详情:', error); let errorMsg = '未知错误'; if (error.response) { // 请求已完成,后端返回错误状态码 console.log('后端状态码:', error.response.status); console.log('后端自定义错误:', error.response.data.error); errorMsg = error.response.data.error || '认证失败'; } else if (error.request) { // 请求发出但没收到服务器响应 errorMsg = '服务器无响应'; } else { // Axios配置或请求初始化出错 errorMsg = error.message; } console.log('最终错误提示:', errorMsg); // 原有清理逻辑保持不变 if (refreshIntervalId) { clearInterval(refreshIntervalId); refreshIntervalId = null; } dispatch('clearUserData', {}); return false; });
二、前端请求的关键配置缺失
你的第一个请求axios.post('/api/keycloak/session/validate')没加withCredentials: true,但后端是从Cookie里读token的!如果是跨域场景,这个请求不会携带Cookie到后端,导致后端返回401,同时浏览器会因为CORS限制,阻止前端读取响应体,直接让Axios抛出异常。
修正第一个请求的配置:
return axios.post('/api/keycloak/session/validate', {}, { withCredentials: true })
(注意第二个参数是空请求体,不能省略,否则配置会被当成请求体传入)
三、后端Lua代码的隐藏bug
我发现你Lua代码里有一处明显的语法错误,虽然可能不是当前问题的直接原因,但会导致其他分支出错:
在IsValidSession函数处理Keycloak返回401的分支里:
elseif res.status == 401 then return respond_error(ngx.ngx.HTTP_UNAUTHORIZED, "Unauthorized session")
这里的ngx.ngx.HTTP_UNAUTHORIZED多了一层ngx.,应该改成ngx.HTTP_UNAUTHORIZED,否则Lua会抛出未定义变量的错误,导致后端返回500而不是预期的401。
四、前端拼写错误(潜在坑)
你的代码里dispatch('startAccesTokenRefreshLoop')中Acces少了一个s,应该是startAccessTokenRefreshLoop。如果这个action不存在,dispatch会抛出错误,虽然当前问题场景可能不会走到这一步,但建议修正避免后续踩坑。
最后验证步骤
- 修正所有代码后,清空浏览器缓存重新测试
- 打开Network面板,确认
/api/keycloak/session/validate请求携带了Cookie(查看Request Headers里的Cookie字段) - 查看控制台输出,确认能拿到后端返回的
No session token错误信息
内容来源于stack exchange

