Skip to content

Commit 66aabb0

Browse files
committed
[CodeQuality] Skip with custom param in previous position on ThrowWithPreviousExceptionRector
1 parent 036cfd3 commit 66aabb0

2 files changed

Lines changed: 44 additions & 6 deletions

File tree

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
namespace Rector\Tests\CodeQuality\Rector\Catch_\ThrowWithPreviousExceptionRector\Fixture;
4+
5+
final class ExceptionWithCustomParam extends \RuntimeException
6+
{
7+
public function __construct(
8+
public readonly bool $flag,
9+
string $message,
10+
int $code = 0,
11+
?\Throwable $previous = null,
12+
) {
13+
parent::__construct($message, $code, $previous);
14+
}
15+
16+
public function run(): void
17+
{
18+
try {
19+
throw new \RuntimeException('root');
20+
} catch (\Throwable $e) {
21+
throw new ExceptionWithCustomParam(flag: true, message: $e->getMessage(), previous: $e);
22+
}
23+
}
24+
}

rules/CodeQuality/Rector/Catch_/ThrowWithPreviousExceptionRector.php

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ private function refactorThrow(Throw_ $throw, Variable $caughtThrowableVariable)
158158
}
159159

160160
if (! isset($new->getArgs()[1])) {
161-
if ($this->hasCodeParameter($new->class)) {
161+
if ($this->hasParameter($new, 'code') && ! $this->hasArgument($new, 'code')) {
162162
// get previous code
163163
$new->args[1] = new Arg(
164164
new MethodCall($caughtThrowableVariable, 'getCode'),
@@ -173,7 +173,7 @@ private function refactorThrow(Throw_ $throw, Variable $caughtThrowableVariable)
173173
/** @var Arg $arg1 */
174174
$arg1 = $new->args[1];
175175
if ($arg1->name instanceof Identifier && $arg1->name->toString() === 'previous') {
176-
if ($this->hasCodeParameter($new->class)) {
176+
if ($this->hasParameter($new, 'code') && ! $this->hasArgument($new, 'code')) {
177177
$new->args[1] = new Arg(
178178
new MethodCall($caughtThrowableVariable, 'getCode'),
179179
name: $shouldUseNamedArguments ? new Identifier('code') : null
@@ -183,11 +183,14 @@ private function refactorThrow(Throw_ $throw, Variable $caughtThrowableVariable)
183183
} elseif (! $hasChanged) {
184184
return null;
185185
}
186-
} else {
186+
} elseif ($this->hasParameter($new, 'previous') && ! $this->hasArgument($new, 'previous')) {
187187
$new->args[$exceptionArgumentPosition] = new Arg(
188188
$caughtThrowableVariable,
189189
name: $shouldUseNamedArguments ? new Identifier('previous') : null
190190
);
191+
$hasChanged = true;
192+
} elseif (! $hasChanged) {
193+
return null;
191194
}
192195

193196
// null the node, to fix broken format preserving printers, see https://github.com/rectorphp/rector/issues/5576
@@ -197,9 +200,9 @@ private function refactorThrow(Throw_ $throw, Variable $caughtThrowableVariable)
197200
return NodeVisitor::DONT_TRAVERSE_CURRENT_AND_CHILDREN;
198201
}
199202

200-
private function hasCodeParameter(Name $exceptionName): bool
203+
private function hasParameter(New_ $new, string $parameterName): bool
201204
{
202-
$className = $this->getName($exceptionName);
205+
$className = $this->getName($new->class);
203206
if (! $this->reflectionProvider->hasClass($className)) {
204207
return false;
205208
}
@@ -217,7 +220,18 @@ private function hasCodeParameter(Name $exceptionName): bool
217220
);
218221

219222
foreach ($extendedParametersAcceptor->getParameters() as $extendedParameterReflection) {
220-
if ($extendedParameterReflection->getName() === 'code') {
223+
if ($extendedParameterReflection->getName() === $parameterName) {
224+
return true;
225+
}
226+
}
227+
228+
return false;
229+
}
230+
231+
private function hasArgument(New_ $new, string $argumentName): bool
232+
{
233+
foreach ($new->getArgs() as $arg) {
234+
if ($arg->name instanceof Identifier && $arg->name->toString() === $argumentName) {
221235
return true;
222236
}
223237
}

0 commit comments

Comments
 (0)