Code Coverage
 
Lines
Branches
Paths
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
18 / 18
93.33% covered (success)
93.33%
14 / 15
90.00% covered (success)
90.00%
9 / 10
85.71% covered (warning)
85.71%
6 / 7
CRAP
0.00% covered (danger)
0.00%
0 / 1
HydrationFailure
100.00% covered (success)
100.00%
18 / 18
93.33% covered (success)
93.33%
14 / 15
90.00% covered (success)
90.00%
9 / 10
100.00% covered (success)
100.00%
7 / 7
9.08
100.00% covered (success)
100.00%
1 / 1
 reason
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 withReason
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 fromHydratableFailure
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 message
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 source
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 formatRowKeys
100.00% covered (success)
100.00%
1 / 1
85.71% covered (warning)
85.71%
6 / 7
66.67% covered (warning)
66.67%
2 / 3
100.00% covered (success)
100.00%
1 / 1
2.15
 valueType
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2
3declare(strict_types=1);
4
5namespace Celema\Quma\Exception;
6
7use RuntimeException;
8use Throwable;
9
10/** @api */
11class HydrationFailure extends RuntimeException
12{
13    private string $reason = '';
14
15    /**
16     * The failure detail without target, source and row keys, so that an
17     * enclosing failure can embed it without repeating its own context.
18     *
19     * @internal
20     */
21    public function reason(): string
22    {
23        return $this->reason;
24    }
25
26    protected function withReason(string $reason): static
27    {
28        $this->reason = $reason;
29
30        return $this;
31    }
32
33    /**
34     * @param class-string $class
35     * @param list<string> $rowKeys
36     */
37    public static function fromHydratableFailure(
38        string $class,
39        ?string $sourcePath,
40        array $rowKeys,
41        Throwable $previous,
42    ): self {
43        return new self(
44            self::message(
45                $class,
46                $sourcePath,
47                'Hydratable::fromRow() failed. Row keys: ' . self::formatRowKeys($rowKeys) . '.',
48            ),
49            0,
50            $previous,
51        );
52    }
53
54    /** @param class-string $class */
55    protected static function message(string $class, ?string $sourcePath, string $detail): string
56    {
57        return "Could not hydrate {$class} from " . self::source($sourcePath) . ": {$detail}";
58    }
59
60    protected static function source(?string $sourcePath): string
61    {
62        return $sourcePath ?? 'ad-hoc SQL';
63    }
64
65    /** @param list<string> $rowKeys */
66    protected static function formatRowKeys(array $rowKeys): string
67    {
68        return $rowKeys === [] ? '(none)' : implode(', ', $rowKeys);
69    }
70
71    protected static function valueType(mixed $value): string
72    {
73        if (is_resource($value)) {
74            return get_resource_type($value) . ' resource';
75        }
76
77        return get_debug_type($value);
78    }
79}

Branches

Below are the source code lines that represent each code branch as identified by Xdebug. Please note a branch is not necessarily coterminous with a line, a line may contain multiple branches and therefore show up more than once. Please also be aware that some branches may be implicit rather than explicit, e.g. an if statement always has an else as part of its logical flow even if you didn't write one.

HydrationFailure->formatRowKeys
66    protected static function formatRowKeys(array $rowKeys): string
67    {
68        return $rowKeys === [] ? '(none)' : implode(', ', $rowKeys);
68        return $rowKeys === [] ? '(none)' : implode(', ', $rowKeys);
68        return $rowKeys === [] ? '(none)' : implode(', ', $rowKeys);
68        return $rowKeys === [] ? '(none)' : implode(', ', $rowKeys);
68        return $rowKeys === [] ? '(none)' : implode(', ', $rowKeys);
68        return $rowKeys === [] ? '(none)' : implode(', ', $rowKeys);
68        return $rowKeys === [] ? '(none)' : implode(', ', $rowKeys);
69    }
HydrationFailure->fromHydratableFailure
38        string $class,
39        ?string $sourcePath,
40        array $rowKeys,
41        Throwable $previous,
42    ): self {
43        return new self(
44            self::message(
45                $class,
46                $sourcePath,
47                'Hydratable::fromRow() failed. Row keys: ' . self::formatRowKeys($rowKeys) . '.',
48            ),
49            0,
50            $previous,
51        );
52    }
HydrationFailure->message
55    protected static function message(string $class, ?string $sourcePath, string $detail): string
56    {
57        return "Could not hydrate {$class} from " . self::source($sourcePath) . ": {$detail}";
58    }
HydrationFailure->reason
23        return $this->reason;
24    }
HydrationFailure->source
60    protected static function source(?string $sourcePath): string
61    {
62        return $sourcePath ?? 'ad-hoc SQL';
63    }
HydrationFailure->valueType
71    protected static function valueType(mixed $value): string
72    {
73        if (is_resource($value)) {
74            return get_resource_type($value) . ' resource';
77        return get_debug_type($value);
78    }
HydrationFailure->withReason
26    protected function withReason(string $reason): static
27    {
28        $this->reason = $reason;
29
30        return $this;
31    }