PHP:如何在Guzzle 4中检查超时异常


PHP: How to check for timeout exception in Guzzle 4?

Guzzle在请求过程中发生错误时抛出异常。不幸的是,似乎没有特定于超时的错误——这对我来说很重要,因为我知道这些错误有时会发生。我想重试相应的请求,并需要能够判断错误是否是由于超时而发生的。

来自文档:

// Timeout if a server does not return a response in 3.14 seconds.
$client->get('/delay/5', ['timeout' => 3.14]);
// PHP Fatal error:  Uncaught exception 'GuzzleHttp'Exception'RequestException'

RequestException在其message属性中具有信息:

"cURL error 28: Operation timed out after 3114 milliseconds with 0 bytes received"

所以我可以评估消息模式,但这感觉有点错误,因为这些消息在未来很容易被更改。

在使用guzzle 4时,是否有更好/更稳定的方法来检查超时

我遇到了同样的问题,我已经通过停止事件的传播来解决它。你可以在这里阅读更多关于这方面的信息。

use GuzzleHttp'Event'ErrorEvent;
use GuzzleHttp'Message'Response;
$client->getEmitter()->on('error', function(ErrorEvent $event) {
    $event->stopPropagation();
    $event->intercept(new Response(200));
    echo $event->getException()->getMessage();
});

在您的情况下,这将输出cURL error 28: Operation timed out after 3114 milliseconds with 0 bytes received而不抛出RequestException

Exeption在此处生成:

https://github.com/guzzle/guzzle/blob/master/src/Adapter/Curl/CurlAdapter.php

private function handleError(
    TransactionInterface $transaction,
    $info,
    $handle
) {
    $error = curl_error($handle);
    $this->releaseEasyHandle($handle);
    RequestEvents::emitError(
        $transaction,
        new AdapterException("cURL error {$info['curl_result']}: {$error}"),
        $info
    );
}

虽然这是一个私人功能,但您有两个选项:

  • 克隆整个文件,给它一个新名称,使用这个而不是CurlAdapter,并引发除"AdapterException"之外的另一个Exception
  • 编辑文件并抛出除"AdapterException"之外的另一个Exeption,但在这种情况下,您的Guzzle不再可维护