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

如何处理Guzzle请求中始终返回200的JSON API错误响应?

如何处理Guzzle请求中返回200状态码的错误响应?

我现在用Guzzle向一个不可控的不可靠数据源发起HTTP请求,这个接口不管成功还是错误都返回200状态码:

  • 成功时返回包含products字段的JSON:
    { "products": { "income": "Income Protection", "car": "Car Insurance" } }
    
  • 错误时返回包含error字段的JSON:
    { "error": "Data source error, please try again" }
    

我的Guzzle请求代码如下:

try {
    $client = new Client(array(
        'curl' => array(
            CURLOPT_SSL_VERIFYPEER => false
        ),
        'verify' => false
    ));
    $res = $client->request($method, self::URI . $url, [ $params ]);
    return $res->getBody();
} catch (ClientException $e) {
    echo Psr7\str($e->getRequest());
    echo Psr7\str($e->getResponse());
}

因为错误响应也是200状态码,所以无法进入catch块,请问该怎么正确处理,返回合适的错误响应?


解决方案

核心思路是不要只依赖HTTP状态码判断请求结果,而是要解析响应体的JSON内容,根据约定的字段(error)来识别错误情况。具体可以这么改:

  1. 先获取响应体并解析为数组/对象
  2. 检查是否存在error字段,如果存在则抛出自定义异常或者直接返回错误响应
  3. 正常情况则返回products数据或者完整响应

修改后的代码示例:

try {
    $client = new Client([
        'curl' => [
            CURLOPT_SSL_VERIFYPEER => false
        ],
        'verify' => false
    ]);
    $res = $client->request($method, self::URI . $url, [ $params ]);
    
    // 读取并解析响应体为关联数组
    $responseBody = $res->getBody()->getContents();
    $responseData = json_decode($responseBody, true);
    
    // 处理JSON解析失败的情况
    if (json_last_error() !== JSON_ERROR_NONE) {
        throw new \Exception('Failed to parse response from data source');
    }
    
    // 检查是否存在约定的错误字段
    if (isset($responseData['error'])) {
        // 这里可以选择抛出自定义异常,方便统一捕获处理
        throw new \Exception($responseData['error']);
        // 或者如果不需要抛出异常,直接返回错误格式的响应:
        // return ['code' => 500, 'message' => $responseData['error']];
    }
    
    // 正常情况返回products数据,或者完整响应数据
    return $responseData['products'] ?? $responseData;
} catch (ClientException $e) {
    // 保留这个分支,以防接口偶尔返回非200状态码的情况
    echo Psr7\str($e->getRequest());
    echo Psr7\str($e->getResponse());
} catch (\Exception $e) {
    // 捕获自定义异常,返回友好的错误响应
    echo 'Request failed: ' . $e->getMessage();
    // 也可以返回结构化的错误数据:
    // return ['error' => $e->getMessage()];
}

额外提醒

  • 生产环境不建议关闭SSL验证(verify => false),最好配置正确的CA证书路径,避免安全风险。
  • 如果接口返回的JSON结构可能有变动,建议增加更多字段校验逻辑,避免因结构异常导致业务报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 13:57:41