Apollo GraphQL错误处理返回无效文档类型(已设JSON内容类型)
问题解决方案
核心原因
json-server 默认在返回404时会生成HTML错误页面,即便你设置了JSON内容类型,当请求头的 Accept 包含 text/html(Apollo Sandbox 默认请求头可能包含该值),就会返回HTML而非JSON,导致Apollo Sandbox识别为无效文档类型。
解决步骤
1. 自定义json-server错误中间件,强制返回JSON格式
创建一个中间件文件(比如 error-middleware.js):
module.exports = (req, res, next) => { // 拦截所有404请求,返回JSON格式错误 const originalSend = res.send; res.send = function(body) { if (res.statusCode === 404 && typeof body === 'string' && body.includes('<html>')) { res.setHeader('Content-Type', 'application/json'); return originalSend.call(this, JSON.stringify({ error: 'Resource not found', statusCode: 404 })); } return originalSend.call(this, body); }; next(); };
启动json-server时加载该中间件:
json-server --watch db.json --middlewares error-middleware.js
2. 确保Apollo Sandbox请求头正确
在Apollo Sandbox的「Headers」标签中,添加或修改 Accept 头为 application/json,避免请求同时接受HTML格式。
3. 优化Apollo Server错误处理逻辑
在Resolver中捕获json-server的响应,确保错误解析和抛出符合GraphQL规范:
async yourResolver(parent, args, context) { try { const response = await fetch('http://your-json-server-endpoint', { headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' } }); if (!response.ok) { // 优先尝试解析JSON错误,若失败则使用默认错误信息 const errorDetails = await response.json().catch(() => ({ message: 'Request failed' })); throw new ApolloError(errorDetails.message, 'INVALID_INPUT', errorDetails); } return await response.json(); } catch (err) { throw new ApolloError(err.message, err.extensions?.code || 'FETCH_FAILED', err); } }
内容的提问来源于stack exchange,提问作者codex
相关产品推荐
相关产品推荐

