Skip to content

Commit 8cf544a

Browse files
committed
Added mapping \ArgumentCountError to better ArgumentCountError.
- Better exception provides two methods: - getExpected(): Returns expected number of arguments. - getActual(): Returns the actual number of arguments.
1 parent be502ef commit 8cf544a

File tree

9 files changed

+254
-5
lines changed

9 files changed

+254
-5
lines changed

README.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,18 @@ Currently only a handful _(in the beginning it was just a single one, since I ne
124124

125125
- `\TypeError` can be converted into:
126126
- `\Smuuf\BetterExceptions\Types\ArgumentTypeError`
127+
- Provides methods:
128+
- `getExpected()`: Returns a list of strings of expected argument types.
129+
- `getActual()`: Returns actual argument type as string.
127130
- `\Smuuf\BetterExceptions\Types\ReturnTypeError`
131+
- _Same as `\Smuuf\BetterExceptions\Types\ArgumentTypeError`._
128132

129133
- `\Error` can be converted into:
130134
- `\Smuuf\BetterExceptions\Types\UnknownNamedParameterError`
131-
135+
- Provides methods:
136+
- `getParameterName()`: Returns the name of unknown parameter as string.
137+
- `\ArgumentCountError` can be converted into:
138+
- `\Smuuf\BetterExceptions\Types\ArgumentCountError`
139+
- Provides methods:
140+
- `getExpected()`: Returns expected number of arguments.
141+
- `getActual()`: Returns the actual number of arguments.
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Smuuf\BetterExceptions\Internals\Processors\Base;
6+
7+
use \Smuuf\BetterExceptions\Types\ArgumentCountError;
8+
use \Smuuf\BetterExceptions\Internals\RegexMatcher;
9+
use \Smuuf\BetterExceptions\Internals\Processors\ProcessorInterface;
10+
11+
abstract class BaseArgumentCountErrorProcessor implements ProcessorInterface {
12+
13+
protected const REGEX =
14+
'#(?<actual>\d+) passed.*(?<expected>\d+) expected#';
15+
16+
public static function process(\Throwable $ex): ?\Throwable {
17+
18+
$msg = $ex->getMessage();
19+
20+
// Is this \Error is about an unknown named parameter?
21+
if ($match = RegexMatcher::match(self::REGEX, $msg)) {
22+
return new ArgumentCountError(
23+
$msg,
24+
(int) $match['expected'],
25+
(int) $match['actual']
26+
);
27+
}
28+
29+
return null;
30+
31+
}
32+
33+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Smuuf\BetterExceptions\Internals\Processors\Php7;
6+
7+
use \Smuuf\BetterExceptions\Internals\Processors\Base\BaseArgumentCountErrorProcessor;
8+
9+
abstract class ArgumentCountErrorProcessor extends BaseArgumentCountErrorProcessor {
10+
11+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Smuuf\BetterExceptions\Internals\Processors\Php8;
6+
7+
use \Smuuf\BetterExceptions\Internals\Processors\Base\BaseArgumentCountErrorProcessor;
8+
9+
abstract class ArgumentCountErrorProcessor extends BaseArgumentCountErrorProcessor {
10+
11+
}

src/Internals/Processors/ProcessorFactory.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ private static function getSpecificProcessor(\Throwable $ex): string {
2222
if (!class_exists($class)) {
2323
throw new ErrorException(sprintf(
2424
"Cannot create better exception from '$exType'"
25-
. " for PHP %s"
25+
. " for PHP %s with message '{$ex->getMessage()}'"
2626
. " (processor '$class' is missing)",
2727
$ver
2828
));

src/Types/ArgumentCountError.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Smuuf\BetterExceptions\Types;
6+
7+
class ArgumentCountError extends \ArgumentCountError {
8+
9+
/** @var int Number of expected arguments. */
10+
protected int $expected;
11+
12+
/** @var int Number of actually passed arguments. */
13+
protected int $actual;
14+
15+
public function __construct(
16+
string $message,
17+
int $expected,
18+
int $actual
19+
) {
20+
21+
parent::__construct($message);
22+
$this->expected = $expected;
23+
$this->actual = $actual;
24+
25+
}
26+
27+
public function getExpected(): int {
28+
return $this->expected;
29+
}
30+
31+
public function getActual(): int {
32+
return $this->actual;
33+
}
34+
35+
36+
}

src/Types/Base/BetterTypeError.php

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,6 @@
99
*/
1010
abstract class BetterTypeError extends \TypeError {
1111

12-
/** @var string Exception message. */
13-
protected $message;
14-
1512
/** @var array<string> List of expected types. */
1613
protected array $expected;
1714

tests/bootstrap.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,29 @@ function get_better_exception(callable $fn, ...$args) {
4545
return BetterException::from($ex);
4646
}
4747

48+
throw new \LogicException("Expected exception but got nothing :(");
49+
50+
}
51+
52+
/**
53+
* Test-driven-development helper for creating new mapping - create new test for
54+
* new mapping and use this helper to see the original exception message.
55+
*
56+
* (Yes, an exception would be printed out anyway by PHP or by Tester, but
57+
* then would terminate. This way you can set up multiple cases and see all
58+
* messages at once.)
59+
*/
60+
function print_exception_message(callable $fn, ...$args) {
61+
62+
try {
63+
$fn(...$args);
64+
} catch (\Throwable $ex) {
65+
66+
$class = get_class($ex);
67+
$parents = implode(' extends ', class_parents($ex));
68+
echo sprintf("Exception: %s (extends $parents)\n", $class);
69+
echo " Message: {$ex->getMessage()}\n";
70+
71+
}
72+
4873
}
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use \Tester\Assert;
6+
7+
use \Smuuf\BetterExceptions\Types\ArgumentCountError;
8+
9+
require __DIR__ . '/../../bootstrap.php';
10+
11+
//
12+
// \Error to UnknownNamedParameterError.
13+
//
14+
15+
function argument_count_error_1($a) {
16+
return $a;
17+
}
18+
19+
function argument_count_error_2($a, $b, $c) {
20+
return $a + $b + $c;
21+
}
22+
23+
function argument_count_error_3($a, $b, $c = null, $d) {
24+
return $a + $b + $c + $d;
25+
}
26+
27+
function argument_count_error_4($a, $b, $c, $d = null) {
28+
return $a + $b + $c + $d;
29+
}
30+
31+
function argument_count_error_5($a, ...$b) {
32+
return $a + $b;
33+
}
34+
35+
function argument_count_error_6($a, $b = null, ...$c) {
36+
return $a + $b + $c;
37+
}
38+
39+
//
40+
//
41+
//
42+
43+
$bex = get_better_exception('argument_count_error_1');
44+
Assert::type(ArgumentCountError::class, $bex);
45+
Assert::same(1, $bex->getExpected());
46+
Assert::same(0, $bex->getActual());
47+
48+
//
49+
//
50+
//
51+
52+
$bex = get_better_exception('argument_count_error_2');
53+
Assert::type(ArgumentCountError::class, $bex);
54+
Assert::same(3, $bex->getExpected());
55+
Assert::same(0, $bex->getActual());
56+
57+
$bex = get_better_exception('argument_count_error_2', 1);
58+
Assert::type(ArgumentCountError::class, $bex);
59+
Assert::same(3, $bex->getExpected());
60+
Assert::same(1, $bex->getActual());
61+
62+
$bex = get_better_exception('argument_count_error_2', 1, 2);
63+
Assert::type(ArgumentCountError::class, $bex);
64+
Assert::same(3, $bex->getExpected());
65+
Assert::same(2, $bex->getActual());
66+
67+
//
68+
//
69+
//
70+
71+
$bex = get_better_exception('argument_count_error_3', );
72+
Assert::type(ArgumentCountError::class, $bex);
73+
Assert::same(4, $bex->getExpected());
74+
Assert::same(0, $bex->getActual());
75+
76+
$bex = get_better_exception('argument_count_error_3', 1);
77+
Assert::type(ArgumentCountError::class, $bex);
78+
Assert::same(4, $bex->getExpected());
79+
Assert::same(1, $bex->getActual());
80+
81+
$bex = get_better_exception('argument_count_error_3', 1, 2);
82+
Assert::type(ArgumentCountError::class, $bex);
83+
Assert::same(4, $bex->getExpected());
84+
Assert::same(2, $bex->getActual());
85+
86+
$bex = get_better_exception('argument_count_error_3', 1, 2, 3);
87+
Assert::type(ArgumentCountError::class, $bex);
88+
Assert::same(4, $bex->getExpected());
89+
Assert::same(3, $bex->getActual());
90+
91+
//
92+
//
93+
//
94+
95+
$bex = get_better_exception('argument_count_error_4', );
96+
Assert::type(ArgumentCountError::class, $bex);
97+
Assert::same(3, $bex->getExpected());
98+
Assert::same(0, $bex->getActual());
99+
100+
$bex = get_better_exception('argument_count_error_4', 1);
101+
Assert::type(ArgumentCountError::class, $bex);
102+
Assert::same(3, $bex->getExpected());
103+
Assert::same(1, $bex->getActual());
104+
105+
$bex = get_better_exception('argument_count_error_4', 1, 2);
106+
Assert::type(ArgumentCountError::class, $bex);
107+
Assert::same(3, $bex->getExpected());
108+
Assert::same(2, $bex->getActual());
109+
110+
//
111+
//
112+
//
113+
114+
$bex = get_better_exception('argument_count_error_5');
115+
Assert::type(ArgumentCountError::class, $bex);
116+
Assert::same(1, $bex->getExpected());
117+
Assert::same(0, $bex->getActual());
118+
119+
//
120+
//
121+
//
122+
123+
$bex = get_better_exception('argument_count_error_6');
124+
Assert::type(ArgumentCountError::class, $bex);
125+
Assert::same(1, $bex->getExpected());
126+
Assert::same(0, $bex->getActual());

0 commit comments

Comments
 (0)