首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如果Laravel中有503个错误,我怎样才能得到Guzzle 6来重试请求?

如果Laravel中有503个错误,我怎样才能得到Guzzle 6来重试请求?
EN

Stack Overflow用户
提问于 2016-02-08 22:33:26
回答 3查看 16.1K关注 0票数 9

我用Laravel5.2编写了一些代码,从不可靠的API源代码中检索结果。但是,它需要能够在失败的尝试中自动重试请求,因为API调用的结果是503次--大约三分之一次。

我用口香糖来做这件事,我想我知道在处理503个响应之前把代码放在哪里,但是我不知道在那里写什么。

在重试过程中,口吻文档并没有提供太多的内容,我所遇到的所有示例都只展示了如何检索结果(我已经可以这样做),而不是如何让它在需要时重复请求。

我绝不要求任何人为我做这项工作,但我认为我对此的理解已接近极限。如果有人能给我指明正确的方向,我会非常感激的:)

编辑:

我会试着修改。请考虑以下代码。在它中,我想发送一个GET请求,这个请求通常会产生一个JSON响应。

DataController.php

代码语言:javascript
运行
复制
$client = new \GuzzleHttp\Client();
$request = $client->request('GET', 'https://httpbin.org/status/503'); // URI is for testing purposes

当来自这个请求的响应是503时,我可以在这里拦截它:

Handler.php

代码语言:javascript
运行
复制
public function render($request, Exception $e)
{
  if ($e->getCode() == 503)
  {
    // Code that would tell Guzzle to retry the request 5 times with a 10s delay before failing completely
  }

  return parent::render($request, $e);
}

我不知道这是不是最好的地方,但真正的问题是我不知道在if ($e->getCode() == 503)里面写什么

EN

回答 3

Stack Overflow用户

发布于 2016-02-09 00:46:35

默认情况下,当返回非2**响应时,例外情况抛出。在你的例子中,你看到了503个答复。异常可以被认为是应用程序可以从中恢复的错误。这是try catch块的工作方式。

代码语言:javascript
运行
复制
try {
    // The code that can throw an exception will go here
    throw new \Exception('A generic error');
    // code from here down won't be executed, because the exception was thrown.
} catch (\Exception $e) {
    // Handle the exception in the best manner possible.
}

将可能在块的try部分抛出异常的代码包装起来。然后将错误处理代码添加到块的catch部分。有关php如何处理异常的更多信息,您可以阅读上面的链接。

对于您的情况,让我们在控制器中移动对它自己的方法的gu包调用:

代码语言:javascript
运行
复制
public function performLookUp($retryOnError = false)
{
    try {
        $client = new \GuzzleHttp\Client();
        $request = $client->request('GET', 'https://httpbin.org/status/503'); 
        return $request->send();
    } catch (\GuzzleHttp\Exception\BadResponseException $e) {
        if ($retryOnError) {
            return $this->performLookUp();
        }
        abort(503);
   }
}

现在在您的控制器中您可以执行,$this->performLookUp(true);

票数 3
EN

Stack Overflow用户

发布于 2016-02-09 13:38:19

只是为了增加一些信息,以澄清洛根提出的几点。

在2**/3**以外的响应上抛出异常。这都取决于GuzzleHttp\HandlerStack是如何创建的。

代码语言:javascript
运行
复制
$stack = GuzzleHttp\HandlerStack::create();
$client = new Client(['handler'=> $stack]);

$client = new Client();
// These two methods of generating a client are functionally the same.


$stack = New GuzzleHttp\HandlerStack(new GuzzleHttp\Handler\CurlHandler());
$client = new Client(['handler'=> $stack]);
// This client will not throw exceptions, or perform any of the functions mentioned below.

create方法将默认处理程序添加到HandlerStack。解析HandlerStack后,处理程序将按以下顺序执行:

  1. 发送请求:
    1. http_errors -发送请求时没有op。当返回响应承诺堆栈时,响应状态代码将在响应处理中被选中。
    2. allow_redirects -发送请求时没有op。当响应承诺在堆栈上返回时,将发生重定向。
    3. cookies将cookie添加到请求中。
    4. prepare_body -将准备HTTP请求的主体(例如,添加默认标题,如内容长度、内容类型等)。
    5. 发送带有处理程序的请求

  1. 处理响应:
    1. prepare_body -没有关于响应处理的操作。
    2. cookie -将响应cookie提取到cookie罐子中。
    3. allow_redirects -跟踪重定向。4.http_errors -当响应状态代码>= 300时抛出异常。

当不提供$handler参数时,GuzzleHttp\HandlerStack::create()将根据系统上可用的扩展选择最合适的处理程序。如处理程序文档中所示

通过手动创建GuzzleHttp\HandlerStack,可以将中间件添加到应用程序中。考虑到您最初的问题“如何重复请求”的上下文,我相信您最感兴趣的是在gues6.1中提供的重试中间件。这是一个中间件,它根据提供的决策函数的结果重试请求。

文档还没有赶上这个类。

票数 3
EN

Stack Overflow用户

发布于 2022-09-02 04:23:01

代码语言:javascript
运行
复制
final class HttpClient extends \GuzzleHttp\Client
{
    public const SUCCESS_CODE = 200;

    private int $attemptsCount = 3;

    private function __construct(array $config = [])
    {
        parent::__construct($config);
    }

    public static function new(array $config = []): self
    {
        return new self($config);
    }

    public function postWithRetry(string $uri, array $options = []): Response
    {
        $attemptsCount = 0;
        $result = null;

        do {

            $attemptsCount++;
            $isEnd = $attemptsCount === $this->attemptsCount;

            try {
                $result = $this->post(
                    $uri,
                    $options,
                );
            } catch (ClientException $e) {
                $result = $e->getResponse();
            } catch (GuzzleException $e) {
                if ($isEnd) {
                    Logger::error($e->getMessage());
                    $result = $e->getResponse();
                }
            }

        } while ($this->isNeedRetry($result, $attemptsCount));

        return $result;
    }

    private function isNeedRetry(?Response $response, int $attemptsCount): bool
    {
        return $response === null && $attemptsCount < $this->attemptsCount;
    }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35280647

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档