Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions extension.neon
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,4 @@ rules:
- PHPStanGlpi\Rules\ForbidExitRule
- PHPStanGlpi\Rules\ForbidHttpResponseCodeRule
- PHPStanGlpi\Rules\MissingGlobalVarTypeRule
- PHPStanGlpi\Rules\ForbidEmptyExceptionMessageRule
72 changes: 72 additions & 0 deletions src/Rules/ForbidEmptyExceptionMessageRule.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<?php

Check warning on line 1 in src/Rules/ForbidEmptyExceptionMessageRule.php

View workflow job for this annotation

GitHub Actions / Check with PHP 8.4

Found violation(s) of type: array_indentation

Check warning on line 1 in src/Rules/ForbidEmptyExceptionMessageRule.php

View workflow job for this annotation

GitHub Actions / Check with PHP 7.4

Found violation(s) of type: array_indentation

declare(strict_types=1);

namespace PHPStanGlpi\Rules;

use PhpParser\Node;
use PhpParser\Node\Expr\New_;
use PHPStan\Analyser\Scope;
use PHPStan\Rules\Rule;
use PHPStan\Rules\RuleErrorBuilder;

/**
* Native PHP exceptions must have an explicit message.
*
* @implements Rule<New_>
*/
final class ForbidEmptyExceptionMessageRule implements Rule
{
private const EXCEPTIONS_TO_CATCH = [
\Exception::class,
\RuntimeException::class,
\LogicException::class,
];

public function getNodeType(): string
{
return New_::class;
}

public function processNode(Node $node, Scope $scope): array
{
if (!$node instanceof New_) {

Check failure on line 33 in src/Rules/ForbidEmptyExceptionMessageRule.php

View workflow job for this annotation

GitHub Actions / Check with PHP 8.4

Instanceof between PhpParser\Node\Expr\New_ and PhpParser\Node\Expr\New_ will always evaluate to true.

Check failure on line 33 in src/Rules/ForbidEmptyExceptionMessageRule.php

View workflow job for this annotation

GitHub Actions / Check with PHP 7.4

Instanceof between PhpParser\Node\Expr\New_ and PhpParser\Node\Expr\New_ will always evaluate to true.
return [];
}


if (!$node->class instanceof Node\Name) {
return [];
}

$className = $node->class->toString();
// not an Exception -> return
if (!is_a($className, \Exception::class, true)) {

Check failure on line 44 in src/Rules/ForbidEmptyExceptionMessageRule.php

View workflow job for this annotation

GitHub Actions / Check with PHP 8.4

Function is_a() is a runtime reflection concept that might not work in PHPStan because it uses fully static reflection engine. Use objects retrieved from ReflectionProvider instead.

Check failure on line 44 in src/Rules/ForbidEmptyExceptionMessageRule.php

View workflow job for this annotation

GitHub Actions / Check with PHP 7.4

Function is_a() is a runtime reflection concept that might not work in PHPStan because it uses fully static reflection engine. Use objects retrieved from ReflectionProvider instead.
return [];
}

// Not an exception to catch
if (!in_array($className, self::EXCEPTIONS_TO_CATCH, true)) {
return [];
}

// Check message argument (empty or not provided)
// exceptions without message may not be reported
// if a single argument is provided with it's name (eg. new \Exception(code: 123))
$no_args = count($node->args) === 0;
// message provided but empty
$emptyMessage = false;
if (!$no_args) {
$firstArg = $node->args[0]->value;

Check failure on line 60 in src/Rules/ForbidEmptyExceptionMessageRule.php

View workflow job for this annotation

GitHub Actions / Check with PHP 8.4

Access to an undefined property PhpParser\Node\Arg|PhpParser\Node\VariadicPlaceholder::$value.

Check failure on line 60 in src/Rules/ForbidEmptyExceptionMessageRule.php

View workflow job for this annotation

GitHub Actions / Check with PHP 7.4

Access to an undefined property PhpParser\Node\Arg|PhpParser\Node\VariadicPlaceholder::$value.
$emptyMessage = $firstArg instanceof Node\Scalar\String_ && trim($firstArg->value) === '';
}

if ($no_args || $emptyMessage) {
return [
RuleErrorBuilder::message('Native PHP exceptions must have an explicit message. ' . $className)->identifier('glpi.forbidEmptyExceptionMessage')->build(),
];
}

return [];
}
}
Loading