Nuxt项目API错误返回异常:statusMessage/message无法正常显示
Nuxt API错误返回异常排查
问题背景
在Nuxt项目的server/api/contact.post.js中处理API错误返回时,遇到了两个异常情况:
问题1:使用statusMessage时返回500错误
最初的catch代码:
catch(error){ console.log(error) sendError(event, createError({ statusCode: 400, statusMessage: error})); }
当传入触发错误的请求体时,console.log(error)正确输出:[ { field: 'email', error: 'Field is required' } ],但接口返回500错误:
{ "url": "/api/contact", "statusCode": 500, "statusMessage": "", "message": "statusMessage.replace is not a function", "stack": "<pre><span class=\"stack internal\">at sanitizeStatusMessage (/C:/Users/User/Desktop/Nuxt/nuxt-test/node_modules/h3/dist/index.mjs:474:24)</span>\n<span class=\"stack internal\">at createError (/C:/Users/user/Desktop/Nuxt/nuxt-test/node_modules/h3/dist/index.mjs:162:30)</span>\n<span class=\"stack\">at /C:/Users/user/Desktop/Nuxt/nuxt-test/.nuxt/dev/index.mjs:814:22</span>\n<span class=\"stack internal\">at process.processTicksAndRejections (node:internal/process/task_queues:95:5)</span>\n<span class=\"stack internal\">at async Object.handler (/C:/Users/user/Desktop/Nuxt/nuxt-test/node_modules/h3/dist/index.mjs:1285:19)</span>\n<span class=\"stack internal\">at async Server.toNodeHandle (/C:/Users/user/Desktop/Nuxt/nuxt-test/node_modules/h3/dist/index.mjs:1360:7)</span></pre>" }
同时控制台提示statusMessage即将被弃用,建议改用message字段。
问题2:改用message后返回结果缺失message字段
修改后的catch代码:
catch(error){ console.log(error) sendError(event, createError({ statusCode: 400, message: error})); }
此时console.log(error)仍能正确输出,但接口返回的错误信息中无message字段:
{ "statusCode": 400, "stack": [] }
完整代码
import nodemailer from 'nodemailer' import validator from 'validator' const config = useRuntimeConfig(); const transporter = nodemailer.createTransport({ host: config.MAILHOST, port: config.MAILPORT, }) export default defineEventHandler (async(event) => { try{ const body = await readBody(event); await isValid(body) const mail = transporter.sendMail({ form: 'test', to: 'here is an email which I switched with this', subject: body.subject, text: body.message, html: body.message, }) return 'Gesendet!' } catch(error){ console.log(error) sendError(event, createError({ statusCode: 400, message: error})); } }) async function isValid(body) { const errors = [] if (validator.isEmpty(body.email || '')) errors.push({ field: 'email', error: 'Field is required' }) if (errors.length > 0) { console.log(errors) return Promise.reject(errors); } else { return Promise.resolve({}) } }
请求体(通过Thunder Client发送)
{ "email":"", "name": "A", "subject": "sub", "message": "Hello Word" }
问题原因及解决方法
核心原因
Nuxt底层依赖的h3框架中,createError方法的statusMessage和message参数仅接受字符串类型。而你的代码中抛出的错误是一个数组([ { field: 'email', error: 'Field is required' } ]),不符合参数类型要求,导致:
- 使用
statusMessage时,内部调用replace方法失败,抛出500错误; - 使用
message时,框架直接忽略非字符串的参数,导致返回结果缺失该字段。
解决方案
方案1:将错误数组转为字符串返回
catch(error){ console.log(error) // 将数组格式的错误转为可读字符串 const errorMsg = Array.isArray(error) ? error.map(item => `${item.field}: ${item.error}`).join('; ') : String(error); sendError(event, createError({ statusCode: 400, message: errorMsg })); }
方案2:返回结构化错误(推荐)
如果需要前端获取完整的错误结构,可以利用createError的data字段携带额外信息:
catch(error){ console.log(error) sendError(event, createError({ statusCode: 400, message: '参数验证失败', data: error // 携带原始错误数组 })); }
此时接口返回结果会包含data字段,前端可从中解析具体的字段错误信息。
优化建议:抛出标准Error对象
修改isValid函数,抛出包含错误数据的标准Error对象,让错误处理更规范:
async function isValid(body) { const errors = [] if (validator.isEmpty(body.email || '')) errors.push({ field: 'email', error: 'Field is required' }) if (errors.length > 0) { console.log(errors) const validationError = new Error('参数验证失败'); validationError.details = errors; return Promise.reject(validationError); } else { return Promise.resolve({}) } }
对应的catch处理:
catch(error){ console.log(error) sendError(event, createError({ statusCode: 400, message: error.message, data: error.details || error })); }
内容的提问来源于stack exchange,提问作者Erik
相关产品推荐
相关产品推荐

