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
相关产品推荐
相关产品推荐

