Passed
Push — 0.6.x ( 8b7bff...29d9ce )
by Shinji
03:20 queued 01:42
created

RetryOnExceptionMiddlewareAsync::invoke()   B

Complexity

Conditions 7
Paths 5

Size

Total Lines 37
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 2
Metric Value
cc 7
eloc 23
nc 5
nop 0
dl 0
loc 37
rs 8.6186
c 2
b 0
f 2
1
<?php
2
3
/**
4
 * This file is part of the sj-i/php-profiler package.
5
 *
6
 * (c) sji <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
declare(strict_types=1);
13
14
namespace PhpProfiler\Lib\Loop\AsyncLoopMiddleware;
15
16
use PhpProfiler\Lib\Log\Log;
17
use PhpProfiler\Lib\Loop\AsyncLoopMiddlewareInterface;
18
use Throwable;
19
20
final class RetryOnExceptionMiddlewareAsync implements AsyncLoopMiddlewareInterface
21
{
22
    private int $current_retry_count = 0;
23
24
    /**
25
     * @param array<int, class-string<Throwable>> $exception_names
0 ignored issues
show
Documentation Bug introduced by
The doc comment array<int, class-string<Throwable>> at position 4 could not be parsed: Unknown type name 'class-string' at position 4 in array<int, class-string<Throwable>>.
Loading history...
26
     */
27
    public function __construct(
28
        private int $max_retry,
29
        private array $exception_names,
30
        private AsyncLoopMiddlewareInterface $chain
31
    ) {
32
    }
33
34
    public function invoke(): \Generator
35
    {
36
        while ($this->current_retry_count <= $this->max_retry or $this->max_retry === -1) {
37
            try {
38
                yield from $this->chain->invoke();
39
            } catch (Throwable $e) {
40
                Log::debug($e->getMessage(), [
41
                    'exception' => $e,
42
                    'trace' => $e->getTrace()
43
                ]);
44
                foreach ($this->exception_names as $exception_name) {
45
                    /** @psalm-suppress DocblockTypeContradiction */
46
                    if (is_a($e, $exception_name)) {
47
                        $this->current_retry_count++;
48
                        Log::debug(
49
                            $e->getMessage(),
50
                            [
51
                                'retry_count' => $this->current_retry_count,
52
                                'trace' => $e->getTrace()
53
                            ]
54
                        );
55
                        continue 2;
56
                    }
57
                }
58
                throw $e;
59
            }
60
            $this->current_retry_count = 0;
61
        }
62
        assert(isset($e) and $e instanceof Throwable);
63
        Log::error(
64
            $e->getMessage(),
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $e does not seem to be defined for all execution paths leading up to this point.
Loading history...
65
            [
66
                'retry_count' => $this->current_retry_count,
67
                'trace' => $e->getTrace()
68
            ]
69
        );
70
        throw $e;
71
    }
72
}
73