在后台进程中,抛出RejectionException而不是ConnectionException

问题描述 投票:2回答:1

我有在多个队列工作器上运行的作业,其中包含一些使用Guzzle的HTTP请求。但是,当我在后台进程中运行这些作业时,此作业中的try-catch块似乎没有出现GuzzleHttp\Exception\RequestException。正在运行的进程是php artisan queue:work,它是Laravel队列系统工作人员,用于监视队列并提取作业。

相反,抛出的异常是消息中的GuzzleHttp\Promise\RejectionException之一:

The promise was rejected with reason: cURL error 28: Operation timed out after 30001 milliseconds with 0 bytes received (see https://curl.haxx.se/libcurl/c/libcurl-errors.html)

这实际上是伪装的GuzzleHttp\Exception\ConnectException(请参阅https://github.com/guzzle/promises/blob/master/src/RejectionException.php#L22),因为如果我在通过访问URL触发的常规PHP流程中运行类似的工作,则确实会获得与消息预期的ConnectException

cURL error 28: Operation timed out after 100 milliseconds with 0 out of 0 bytes received (see https://curl.haxx.se/libcurl/c/libcurl-errors.html)

将触发此超时的示例代码:

$c = new \GuzzleHttp\Client([
    'timeout' => 0.1
]);
$response = (string) $c->get('https://example.com')->getBody();

因此,我基本上得出的是,此RejectionException正在包装来自ConnectException的消息,但是我没有使用Guzzle的异步功能。我的要求只是简单地按顺序完成。唯一不同的是,多个PHP进程可能正在进行Guzzle HTTP调用,或者作业本身正在超时(这将导致Laravel的Illuminate\Queue\MaxAttemptsExceededException出现另一个异常),但是我不明白这是如何导致代码行为的不同地。

我无法在Guzzle软件包内找到使用php_sapi_name() / PHP_SAPI(确定所使用的接口)来执行从命令行界面(而不是浏览器触发器)执行不同内容的所有代码。

tl; dr

为什么Guzzle会在工作进程中抛出RejectionException,而在通过浏览器触发的常规PHP脚本中却抛出ConnectException

php laravel queue background-process guzzle
1个回答
0
投票

您好,我想知道您是否遇到错误4xx或错误5xx

但是即使如此,我还是会为发现与您的问题类似的解决方案提供一些替代方案

替代1

我想解决这个问题,与开发和测试环境按预期运行相比,新的生产服务器返回了意外的400个响应,这是我遇到的问题;只需安装apt install php7.0-curl即可修复它。

这是一个全新的Ubuntu 16.04 LTS安装,通过ppa:ondrej / php安装了php,在调试过程中,我注意到标题不同。两者都发送包含被查封数据的多部分表单,但是如果没有php7.0-curl,则发送的是Connection:close标头,而不是Expect:100-Continue;两个请求都具有Transfer-Encoding:分块。

替代2

也许您应该试试这个

try {
$client = new Client();
$guzzleResult = $client->put($url, [
    'body' => $postString
]);
} catch (\GuzzleHttp\Exception\RequestException $e) {
$guzzleResult = $e->getResponse();
}

var_export($guzzleResult->getStatusCode());
var_export($guzzleResult->getBody());

如果响应代码不是200,则需要钳住嘴

替代3

在我的情况下,因为我在请求的$ options ['json']中传递了一个空数组即使传递Content-Type:application / json请求标头,我也无法使用Postman或cURL在服务器上复制500。

无论如何,从请求的选项数组中删除json键解决了问题。

我花了大约30分钟的时间试图找出问题所在,因为这种行为非常不一致。对于我正在执行的所有其他请求,传递$ options ['json'] = []不会引起任何问题。可能是服务器问题,我无法控制服务器。

发送有关获得的详细信息的反馈

© www.soinside.com 2019 - 2024. All rights reserved.