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

使用await fetch无法获取Node.js Express后端自定义错误消息

解决Fetch API无法读取Express后端自定义错误响应的问题

我在Node.js Express后端实现了自定义错误处理器,返回包含自定义消息的JSON响应:

res.status(error.status || 500).json({
  status: error.status || 500,
  message: 'MY CUSTOM ERROR MESSAGE',
  stack: error.stack
})

之前用jQuery Ajax能正常获取自定义错误消息:

$.ajaxSetup({
  error(jqXHR, exception) {
    $('#divSubmitButtonSpinAnimation').addClass('d-none');

    $.toast({
      position: 'top-right',
      dismissible: true,
      stackable: true,
      pauseDelayOnHover: true,
      title: jqXHR.statusText,
      subtitle: jqXHR.status,
      content: (jqXHR.responseJSON) ? jqXHR.responseJSON.message : 'Unspecified Error',
      type: 'error',
      delay: 5000,
    });

    return false;
  },
});

但改用await fetch API后,能拿到500状态码和默认的"Internal Server Error"状态文本,却无法读取自定义的response.message(值为undefined)。


问题原因

Fetch API和jQuery Ajax的核心行为差异导致了这个问题:

  1. 响应解析方式不同:jQuery会自动将JSON格式的响应解析为responseJSON对象;而Fetch返回的response是一个Response元数据对象,需要手动调用.json()方法异步解析响应体才能拿到实际的JSON数据。
  2. 错误触发逻辑不同:jQuery会把所有HTTP错误状态(4xx/5xx)直接触发error回调;但Fetch只有在网络层面失败时才会进入catch,HTTP错误状态(比如500)仍会进入then回调,需要手动判断状态码。

解决方案

使用Fetch时,需要先判断响应状态,再手动解析错误响应的JSON内容,示例代码如下:

try {
  const response = await fetch('/your-api-path', {
    method: 'POST', // 根据实际请求方式调整
    headers: {
      'Content-Type': 'application/json' // 上传文件时需改为multipart/form-data或对应格式
    },
    body: JSON.stringify(yourRequestData) // 文件上传时需用FormData
  });

  // 检查响应是否为成功状态(200-299)
  if (!response.ok) {
    // 解析错误响应的JSON内容
    const errorData = await response.json();
    // 此时可以拿到自定义错误消息
    console.log(errorData.message);

    // 沿用之前的toast提示逻辑
    $('#divSubmitButtonSpinAnimation').addClass('d-none');
    $.toast({
      position: 'top-right',
      dismissible: true,
      stackable: true,
      pauseDelayOnHover: true,
      title: response.statusText,
      subtitle: response.status,
      content: errorData.message || 'Unspecified Error',
      type: 'error',
      delay: 5000,
    });

    // 抛出错误终止后续逻辑(可选)
    throw new Error(errorData.message);
  }

  // 正常响应的处理逻辑
  const data = await response.json();
  // ...
} catch (error) {
  // 捕获网络错误或手动抛出的错误
  $('#divSubmitButtonSpinAnimation').addClass('d-none');
  $.toast({
    position: 'top-right',
    dismissible: true,
    stackable: true,
    pauseDelayOnHover: true,
    title: '请求异常',
    subtitle: '网络错误',
    content: 'Unspecified Error',
    type: 'error',
    delay: 5000,
  });
}

关键注意点

  • 必须通过response.ok判断响应状态,HTTP错误状态(如500)不会自动触发catch。
  • 解析响应体的.json()是异步操作,必须用await等待完成才能拿到错误数据。
  • 文件上传场景下,请求头和body需要调整为FormData格式,不要设置Content-Type(浏览器会自动生成正确的边界标识)。

内容的提问来源于stack exchange,提问作者goxarad784

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 06:15:13