如何处理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)来识别错误情况。具体可以这么改:
- 先获取响应体并解析为数组/对象
- 检查是否存在
error字段,如果存在则抛出自定义异常或者直接返回错误响应 - 正常情况则返回
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
相关产品推荐
相关产品推荐

