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

useMutation为何无法检测到服务器返回的错误?

问题排查:useMutation删除操作500错误但onSuccess/onError未触发

现象

调用useMutation执行删除操作时,服务器返回500错误,但onSuccess和onError回调均未触发,控制台仅输出:

DELETE http://localhost:3000/api/facturas/46 net::ERR_ABORTED 500 (Internal Server Error)

相关实现代码:

const { mutate: handleDelete } = useMutation({
  mutationFn: async () => {
    const response = await fetch(`/api/pagos-recibidos/${view}`, {
      headers: {
        access_token: access_token,
      },
      method: "DELETE",
    });

    if (!response.ok) {
      const errorData = await response.json();
      throw new Error(errorData.message || "Failed to delete payment");
    }

    return response.json();
  },
  onSuccess: () => {
    const params = new URLSearchParams(searchParams?.toString());
    params.delete("view");
    router.push(`?${params.toString()}`);
    toast.success("Factura eliminada exitosamente");
  },
  onError: (error) => {
    console.error("Delete error:", error.message);
    toast.error(
      error.message || "An error occurred while deleting the payment",
    );
  },
});

原因分析

1. 请求被主动中止(ERR_ABORTED)

net::ERR_ABORTED是核心线索——这个错误说明请求并非正常完成,而是被中途取消了。常见触发场景:

  • 触发删除后,页面立即执行跳转/组件被卸载(比如误在删除触发后直接调用router.push,而非等待请求完成)
  • 代码中存在AbortController主动中止请求的逻辑(当前代码未体现,但需排查关联逻辑)

2. 500响应的JSON解析失败

你在!response.ok分支尝试用response.json()解析错误,但如果服务器返回的500响应不是合法JSON格式(比如返回纯文本"Internal Server Error"),response.json()会抛出语法错误,且这个错误未被捕获,导致mutationFn的异常无法正确传递给useMutation的错误处理机制。

3. 请求URL路径不一致

控制台显示请求的是/api/facturas/46,但代码中请求路径为/api/pagos-recibidos/${view}。要么是view变量值错误,要么是后端接口路由与前端调用路径不匹配,导致请求到错误接口,进而触发异常并可能被中止。

修复方案

  • 锁定请求中止原因:调用handleDelete后,不要立即执行页面跳转或组件卸载操作,先在mutationFn关键位置添加日志(比如console.log("Response status:", response.status)),确认是否能进入错误处理分支。
  • 处理JSON解析异常:给response.json()添加try-catch,避免解析失败导致异常丢失:
if (!response.ok) {
  let errorMessage = "Failed to delete payment";
  try {
    const errorData = await response.json();
    errorMessage = errorData.message || errorMessage;
  } catch (parseError) {
    // 处理非JSON格式的错误响应
    errorMessage = await response.text() || errorMessage;
  }
  throw new Error(errorMessage);
}
  • 校验请求URL一致性:确认view变量的值是否为46,以及后端是否存在/api/pagos-recibidos/46这个删除接口,而非控制台显示的/api/facturas/46。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 00:26:12