【问题标题】:Catch Guzzle exceptions on connections refused在连接被拒绝时捕获 Guzzle 异常
【发布时间】:2021-02-19 21:55:31
【问题描述】:

我正在使用带有以下代码的 Guzzle:

try {
    $client = new Client();
    $result = $client->get("http://{$request->ES_HOST}:{$request->ES_PORT}", [
            'headers' => ['Content-Type' => 'application/json'],
            'auth' => [$request->ES_LOGIN, $request->ES_PASSWORD],
            'allow_redirects' => false,
        ]);
    $response['status'] = $result->getStatusCode();
    $response['message'] = json_decode($result->getBody()->getContents());
} catch (RequestException $e) {
    $response['status'] = $e->getResponse()->getStatusCode();
    $response['message'] = $e->getMessage();
}

而且它运行良好,但是当用户为 guzzle 提供错误的 URL 来处理它而不是在 RequestException 中被捕获时,它会在服务器中给出 500 错误并返回带有 cURL error 7: Failed to connect to [host] port [port]: Connection refused 消息的常规 Exception .我可以这样做,以便我可以捕获错误和状态代码并返回给用户吗?

【问题讨论】:

  • 你能删除 try-catch 块并检查内部日志引发了什么样的异常吗?

标签: php laravel guzzle


【解决方案1】:

试过你的代码,它似乎抛出了GuzzleHttp\Exception\ConnectException的一个实例,所以把catch改成

} catch (ConnectException $e) {
    $response['status'] = 'Connect Exception';
    $response['message'] = $e->getMessage();
}

(添加适当的use语句...

use GuzzleHttp\Exception\ConnectException;

)

还注意到它没有$e->getResponse()->getStatusCode(),这就是为什么我将它设置为固定字符串。

【讨论】:

  • 相同的结果,因为 RequestException 已经有 ConnectException。docs.guzzlephp.org/en/stable/quickstart.html#exceptions
  • @MathiasHillmann 有趣的是github.com/guzzle/guzzle/blob/master/src/Exception/… 的来源有class ConnectException extends TransferException
  • 在弄乱了代码之后,您似乎是正确的并且文档不正确(?),ConnectException 确实捕获了它,但是我需要请求的状态代码。
  • @MathiasHillmann,什么状态码?连接失败,所以没有状态。
  • 如果你只想捕获RequestException,那么一旦在catch中使用$e->hasResponse(),如果它是假的,那么没有连接因此没有状态码&没有getResponse()如果是真的然后记录getResponse()getStatusCode()
【解决方案2】:

由于 Guzzle 有这么多异常,我最终检查了 guzzle 抛出了哪种类型的异常并相应地构建了响应:

try {
    $client = new Client();
    $result = $client->get("http://{$request->ES_HOST}:{$request->ES_PORT}", [
            'headers' => ['Content-Type' => 'application/json'],
            'auth' => [$request->ES_LOGIN, $request->ES_PASSWORD],
            'allow_redirects' => false,
        ]);
    $response['status'] = $result->getStatusCode();
    $response['message'] = json_decode($result->getBody()->getContents());
} catch (ConnectException $e) {
    $response['status'] = 404;
    $response['message'] = $e->getMessage();
} catch (RequestException $e) {
    $response['status'] = $e->getResponse()->getStatusCode();
    $response['message'] = $e->getMessage();
} catch (\Exception $e) {
    $response['status'] = 0;
    $response['message'] = $e->getMessage();
}

【讨论】:

  • 在最后的 catch() 块中,添加 print_r($e); 并查看异常是什么类型。
  • 不需要你的脏东西,只要检查它是否有Response(),如果没有,则它从未发送过,因此没有连接,@NigelRen 方法也可以工作
  • @NigelRen 它给出了一个 ConnectException
  • 这不是我建议的吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-10-13
  • 1970-01-01
  • 2016-06-24
  • 1970-01-01
  • 1970-01-01
  • 2013-06-29
  • 1970-01-01
相关资源
最近更新 更多