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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 21:12:36