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

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' } ]),不符合参数类型要求,导致:

  1. 使用statusMessage时,内部调用replace方法失败,抛出500错误;
  2. 使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 01:17:20