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

Promise返回400状态码时仍触发then回调执行的问题

问题根源
  • 你对Promise的基础理解没错:then 仅会在Promise状态变为fulfilled(成功兑现)时触发,400等错误状态下进入then,本质是当前请求逻辑把这类错误响应当成了成功状态resolve了,和Promise本身机制无关。
  • 如果你用的是原生fetch API:这是fetch的默认设计,只有断网、跨域拦截、请求超时这类完全没拿到服务器响应的场景才会reject进catch,只要服务器返回了HTTP响应(哪怕是400/500错误),都会走resolve逻辑进入then。
  • 如果你用的是axios这类二次封装的请求库:默认配置下2xx状态码才会resolve,非2xx会自动reject。出现400进then的情况,大概率是你全局或单请求修改了validateStatus配置,比如设置为() => true强制所有状态都走resolve。
  • 你当前的代码是嵌套Promise的回调地狱写法,内部PUT请求的错误无法被外层catch捕获,很容易出现错误漏处理的问题。
修复方案

1. 补全错误状态校验逻辑

如果用原生fetch,必须在第一层then里手动校验响应状态,不满足成功条件就主动抛错进入catch:

// fetch 校验示例
fetch("/api/v1/file/upload", {
  method: "POST",
  body: formdata
})
.then(response => {
  // 手动校验状态,非2xx直接抛错
  if (!response.ok) {
    return Promise.reject(new Error(`上传失败,状态码:${response.status}`))
  }
  return response.json()
})

如果用axios,先检查全局validateStatus配置,改回默认规则即可:

// axios全局配置修正
axios.defaults.validateStatus = (status) => {
  // 仅2xx状态判定为成功
  return status >= 200 && status < 300
}

如果需要保留特殊的validateStatus配置,也可以在业务代码的then里手动加状态校验,不符合预期就主动返回Promise.reject()抛错。

2. 优化Promise写法,避免回调地狱

不要嵌套写then,把内部Promise return出去做链式调用,保证所有环节的错误都能被最后一个catch捕获:

const formdata = new FormData();
formdata.append("file", image.file);
api
  .post("/api/v1/file/upload", formdata)
  .then((response) => {
    // 这里可以加兜底状态校验
    if (response.status !== 200) return Promise.reject(new Error("文件上传失败"))
    const imageUrl = response.data.url
    // 把内部请求的Promise return出去,透传到外层链式调用
    return api.put(`/api/v1/radio/${id}`, {
      name: name,
      email: email,
      image: imageUrl,
    })
  })
  .then(response => {
    console.log("全流程执行成功", response);
  })
  .catch(error => {
    console.log("流程异常:", error);
  })

更推荐用async/await写法,逻辑和同步代码一致,维护成本更低:

async function submitForm() {
  try {
    const formdata = new FormData();
    formdata.append("file", image.file);
    const uploadRes = await api.post("/api/v1/file/upload", formdata);
    // 兜底校验上传结果
    if (uploadRes.status !== 200) throw new Error("文件上传失败");
    const imageUrl = uploadRes.data.url;
    const updateRes = await api.put(`/api/v1/radio/${id}`, {
      name: name,
      email: email,
      image: imageUrl,
    });
    console.log("提交成功", updateRes);
  } catch (error) {
    console.log("提交失败:", error);
  }
}

// 调用函数执行逻辑
submitForm()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 11:39:40