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

Next JS中GraphQL mutation失败后触发ERR_HTTP_HEADERS_SENT错误求助

Next.js API Route中Apollo Mutation触发ERR_HTTP_HEADERS_SENT的问题解决

问题场景与代码示例

我正在使用Next.js API Routes,在其中一个路由里通过Apollo调用GraphQL mutation,代码如下:

// pages/api/foo.js

import { initializeApollo } from '~/server/apollo'

export default function handler(req, res) {
  const client = initializeApollo()
  try {
    await client.mutate({ mutation: FooDocument })
    // 此分支正常
    res.status(200).send({ foo: '...' })
  } catch {
    // 此分支报错
    res.status(500).send({ error: '...' })
  }
}

遇到的问题:当mutation执行失败进入catch块时,调用res.status(500).send({ error: '...' })会触发服务器错误:

Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client

但mutation执行成功时,res.status(200).send({ foo: '...' })可以正常运行。

问题原因

核心问题是handler函数没有标记为async,但代码里使用了await client.mutate(...)异步操作。

当代码执行到await时,会暂时跳出handler函数,Next.js会误以为请求已经处理完成,自动向客户端发送了响应头。后续mutation执行失败进入catch块时,再调用res.send就属于重复设置响应头,因此触发这个错误。

成功分支看似正常,只是因为await后的同步代码刚好在Next.js自动响应前执行完毕,属于偶然情况,代码本身存在逻辑漏洞。

后端解决办法

给handler函数添加async关键字,让Next.js明确这是异步处理函数,会等待所有异步操作完成后再结束请求:

修改后的代码:

// pages/api/foo.js

import { initializeApollo } from '~/server/apollo'

export default async function handler(req, res) {
  const client = initializeApollo()
  try {
    await client.mutate({ mutation: FooDocument })
    res.status(200).send({ foo: '...' })
  } catch (err) {
    // 捕获错误对象,返回更具体的错误信息
    res.status(500).send({ error: err.message || 'mutation执行失败' })
  }
}

额外建议:在catch块中捕获具体的错误对象,既能返回更精准的错误信息给前端,也方便后续通过日志排查问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 11:42:24