Completed
Pull Request — master (#129)
by Eric
257:01 queued 192:06
created

src/Event/Subscriber/RetrySubscriber.php (4 issues)

Labels
Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
/*
4
 * This file is part of the Ivory Http Adapter package.
5
 *
6
 * (c) Eric GELOEN <[email protected]>
7
 *
8
 * For the full copyright and license information, please read the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Ivory\HttpAdapter\Event\Subscriber;
13
14
use Ivory\HttpAdapter\Event\Events;
15
use Ivory\HttpAdapter\Event\RequestErroredEvent;
16
use Ivory\HttpAdapter\Event\MultiRequestErroredEvent;
17
use Ivory\HttpAdapter\Event\Retry\Retry;
18
use Ivory\HttpAdapter\Event\Retry\RetryInterface;
19
use Ivory\HttpAdapter\HttpAdapterException;
20
use Ivory\HttpAdapter\MultiHttpAdapterException;
21
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
22
23
/**
24
 * Retry subscriber.
25
 *
26
 * @author GeLo <[email protected]>
27
 */
28
class RetrySubscriber implements EventSubscriberInterface
29
{
30
    /** @var \Ivory\HttpAdapter\Event\Retry\RetryInterface */
31
    private $retry;
32
33
    /**
34
     * Creates a retry subscriber.
35
     *
36
     * @param \Ivory\HttpAdapter\Event\Retry\RetryInterface|null $retry The retry.
37
     */
38 171
    public function __construct(RetryInterface $retry = null)
39
    {
40 171
        $this->retry = $retry ?: new Retry();
41 171
    }
42
43
    /**
44
     * Gets the retry.
45
     *
46
     * @return \Ivory\HttpAdapter\Event\Retry\RetryInterface The retry.
47
     */
48 38
    public function getRetry()
49
    {
50 38
        return $this->retry;
51
    }
52
53
    /**
54
     * {@inheritdoc}
55
     */
56 57
    public function onRequestErrored(RequestErroredEvent $event)
57
    {
58 57
        if (($request = $this->retry->retry($event->getException()->getRequest())) === false) {
0 ignored issues
show
It seems like $event->getException()->getRequest() can be null; however, retry() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
59 19
            return;
60
        }
61
62 38
        $event->getException()->setRequest($request);
0 ignored issues
show
It seems like $request defined by $this->retry->retry($eve...eption()->getRequest()) on line 58 can also be of type boolean; however, Ivory\HttpAdapter\HttpAd...Exception::setRequest() does only seem to accept null|object<Ivory\HttpAd...ternalRequestInterface>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
63
64
        try {
65 38
            $event->setResponse($event->getHttpAdapter()->sendRequest($request));
0 ignored issues
show
It seems like $request defined by $this->retry->retry($eve...eption()->getRequest()) on line 58 can also be of type boolean; however, Ivory\HttpAdapter\PsrHtt...nterface::sendRequest() does only seem to accept object<Psr\Http\Message\RequestInterface>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
66 37
        } catch (HttpAdapterException $e) {
67 19
            $event->setException($e);
68
        }
69 38
    }
70
71
    /**
72
     * On multi request errored event.
73
     *
74
     * @param \Ivory\HttpAdapter\Event\MultiRequestErroredEvent $event The multi request errored event.
75
     */
76 57
    public function onMultiResponseErrored(MultiRequestErroredEvent $event)
77
    {
78 57
        $retryRequests = array();
79
80 57
        foreach ($event->getExceptions() as $exception) {
81 57
            if (($request = $this->retry->retry($exception->getRequest(), false)) !== false) {
0 ignored issues
show
It seems like $exception->getRequest() can be null; however, retry() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
82 38
                $retryRequests[] = $request;
83 39
                $event->removeException($exception);
84 36
            }
85 54
        }
86
87 57
        if (empty($retryRequests)) {
88 19
            return;
89
        }
90
91
        try {
92 38
            $event->addResponses($event->getHttpAdapter()->sendRequests($retryRequests));
93 37
        } catch (MultiHttpAdapterException $e) {
94 19
            $event->addResponses($e->getResponses());
95 19
            $event->addExceptions($e->getExceptions());
96
        }
97 38
    }
98
99
    /**
100
     * {@inheritdoc}
101
     */
102 19
    public static function getSubscribedEvents()
103
    {
104
        return array(
105 19
            Events::REQUEST_ERRORED       => array('onRequestErrored', 0),
106 18
            Events::MULTI_REQUEST_ERRORED => array('onMultiResponseErrored', 0),
107 18
        );
108
    }
109
}
110