Skip to content

Commit 56a648d

Browse files
committed
Refactor Exception Classes to Include Error Code Constants
- **Added numeric error code constants** to all exception classes in `src/` directory. - Each exception class now defines private constants for error codes. - Factory methods updated to use these constants when creating `ExceptionMessage` instances. - **Modified `ExceptionMessage` class** to accept `int $code` as the first parameter. - Updated constructor signature to `public function __construct(int $code, string $errorCode, string $message)`. - Ensured compatibility across all usages. - **Updated `AbstractException` class**: - Constructor now sets the numeric code from `ExceptionMessage` using `$errorMessage->getCode()`. - Maintains error code string and context. - **Refactored exception tests in `tests/` directory**: - Updated `assertExceptionStructure` method in `AbstractExceptionTest` to include assertion for numeric error code. - All exception test classes now pass the expected numeric code to `assertExceptionStructure`. - Ensured that all tests reflect the changes in the exception classes and pass successfully. - **Consistent Error Code Ranges**: - Established a consistent error code range for each exception type as per the error code range table. - This enhances error categorization and future maintainability. **Summary:** This commit refactors the exception handling mechanism by introducing numeric error code constants across all exception classes and their corresponding tests. This change enhances the clarity and maintainability of the codebase by: - Providing a standardized way to identify exceptions through numeric codes. - Improving error categorization according to the defined error code ranges. - Ensuring consistency between the exception classes and their tests. - Facilitating better integration with logging and error handling systems that utilize numeric error codes.
1 parent 35234ef commit 56a648d

File tree

52 files changed

+788
-134
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+788
-134
lines changed

script.php

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
require 'vendor/autoload.php';
6+
require 'code_mapping.php';
7+
8+
use PhpParser\Error;
9+
use PhpParser\Modifiers;
10+
use PhpParser\Node;
11+
use PhpParser\Node\Scalar\Int_;
12+
use PhpParser\Node\Scalar\LNumber;
13+
use PhpParser\NodeTraverser;
14+
use PhpParser\NodeVisitorAbstract;
15+
use PhpParser\ParserFactory;
16+
use PhpParser\PrettyPrinter;
17+
use PhpParser\NodeVisitor\ParentConnectingVisitor;
18+
use PhpParser\NodeVisitor\NameResolver;
19+
use PhpParser\Node\Stmt\Class_;
20+
21+
// Diretório base a ser vasculhado
22+
$baseDir = __DIR__ . '/src'; // Altere para o caminho correto
23+
24+
// Função para percorrer o diretório recursivamente
25+
function scanDirectory(string $dir, array $codeMapping)
26+
{
27+
$files = scandir($dir);
28+
foreach ($files as $file) {
29+
if ($file === '.' || $file === '..') {
30+
continue;
31+
}
32+
$filePath = $dir . DIRECTORY_SEPARATOR . $file;
33+
if (is_dir($filePath)) {
34+
scanDirectory($filePath, $codeMapping);
35+
} elseif (is_file($filePath) && pathinfo($filePath, PATHINFO_EXTENSION) === 'php') {
36+
processFile($filePath, $codeMapping);
37+
}
38+
}
39+
}
40+
41+
// Função para processar cada arquivo
42+
function processFile(string $filePath, array $codeMapping)
43+
{
44+
$code = file_get_contents($filePath);
45+
46+
$parserFactory = new ParserFactory();
47+
$parser = $parserFactory->createForNewestSupportedVersion();
48+
49+
try {
50+
$ast = $parser->parse($code);
51+
} catch (Error $error) {
52+
echo "Erro ao analisar o arquivo {$filePath}: {$error->getMessage()}\n";
53+
return;
54+
}
55+
56+
$traverser = new NodeTraverser();
57+
58+
// Adicionar NameResolver
59+
$traverser->addVisitor(new NameResolver());
60+
61+
// Adicionar ParentConnectingVisitor
62+
$traverser->addVisitor(new ParentConnectingVisitor());
63+
64+
$visitor = new class ($codeMapping) extends NodeVisitorAbstract {
65+
private $codeMapping;
66+
private $currentClass;
67+
private $classNode;
68+
69+
public function __construct(array $codeMapping)
70+
{
71+
$this->codeMapping = $codeMapping;
72+
}
73+
74+
public function enterNode(Node $node)
75+
{
76+
if ($node instanceof Node\Stmt\Class_) {
77+
if (isset($node->namespacedName)) {
78+
$this->currentClass = $node->namespacedName->toString();
79+
} else {
80+
$this->currentClass = $node->name->toString();
81+
}
82+
$this->classNode = $node;
83+
}
84+
85+
if ($node instanceof Node\Stmt\ClassMethod && $node->isStatic()) {
86+
if ($this->currentClass && isset($this->codeMapping[$this->currentClass])) {
87+
$methodName = $node->name->toString();
88+
if (isset($this->codeMapping[$this->currentClass][$methodName])) {
89+
$codeInt = $this->codeMapping[$this->currentClass][$methodName];
90+
91+
// Adicionar a constante de código inteiro na classe, se ainda não existir
92+
$constName = 'CODE_' . strtoupper($methodName);
93+
94+
// Verificar se a constante já existe
95+
$constExists = false;
96+
foreach ($this->classNode->stmts as $stmt) {
97+
if ($stmt instanceof Node\Stmt\ClassConst) {
98+
foreach ($stmt->consts as $const) {
99+
if ($const->name->toString() === $constName) {
100+
$constExists = true;
101+
break 2;
102+
}
103+
}
104+
}
105+
}
106+
107+
if (!$constExists) {
108+
$const = new Node\Stmt\ClassConst(
109+
[
110+
new Node\Const_(
111+
new Node\Identifier($constName),
112+
new Int_($codeInt)
113+
)
114+
],
115+
Modifiers::PRIVATE
116+
);
117+
118+
// Inserir a constante no início dos statements da classe
119+
array_unshift($this->classNode->stmts, $const);
120+
}
121+
}
122+
}
123+
}
124+
}
125+
};
126+
127+
$traverser->addVisitor($visitor);
128+
$modifiedAst = $traverser->traverse($ast);
129+
130+
// Converter o AST de volta para código PHP
131+
$prettyPrinter = new PrettyPrinter\Standard();
132+
$modifiedCode = $prettyPrinter->prettyPrintFile($modifiedAst);
133+
134+
// Salvar o código modificado de volta no arquivo
135+
file_put_contents($filePath, $modifiedCode);
136+
echo "Arquivo atualizado: {$filePath}\n";
137+
}
138+
139+
// Iniciar o processo de varredura
140+
scanDirectory($baseDir, $codeMapping);
141+
142+
echo "Atualização concluída.\n";

src/AbstractException.php

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,26 @@
1010
abstract class AbstractException extends \Exception implements Throwable
1111
{
1212
protected array $context = [];
13+
private string $errorCode;
1314

1415
public function __construct(ErrorMessage $errorMessage, ?\Throwable $previous = null, array $context = [])
1516
{
17+
$this->errorCode = $errorMessage->getErrorCode();
18+
$this->context = array_merge(['code' => $this->errorCode], $context);
1619

17-
$this->context = array_merge(['code' => $errorMessage->getCode()], $context);
18-
19-
parent::__construct($errorMessage->getMessage(), 0, $previous);
20+
parent::__construct($errorMessage->getMessage(), $errorMessage->getCode(), $previous);
2021
}
2122

2223
public function getContext(): array
2324
{
2425
return $this->context;
2526
}
2627

28+
public function getErrorCode(): string
29+
{
30+
return $this->errorCode;
31+
}
32+
2733
protected function addContext(string $key, mixed $value): self
2834
{
2935
$this->context[$key] = $value;

src/Auth/AuthenticationException.php

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,34 @@
99

1010
final class AuthenticationException extends AbstractException
1111
{
12+
private const CODE_INVALID_CREDENTIALS = 1001;
13+
private const CODE_ACCOUNT_LOCKED = 1002;
14+
private const CODE_TWO_FACTOR_REQUIRED = 1003;
15+
1216
public static function invalidCredentials(): self
1317
{
14-
return new self(new ExceptionMessage('INVALID_CREDENTIALS', 'Invalid credentials provided'));
18+
return new self(new ExceptionMessage(
19+
self::CODE_INVALID_CREDENTIALS,
20+
'INVALID_CREDENTIALS',
21+
'Invalid credentials provided'
22+
));
1523
}
1624

1725
public static function accountLocked(): self
1826
{
19-
return new self(new ExceptionMessage('ACCOUNT_LOCKED', 'Account is locked'));
27+
return new self(new ExceptionMessage(
28+
self::CODE_ACCOUNT_LOCKED,
29+
'ACCOUNT_LOCKED',
30+
'Account is locked'
31+
));
2032
}
2133

2234
public static function twoFactorRequired(): self
2335
{
24-
return new self(new ExceptionMessage('TWO_FACTOR_REQUIRED', 'Two-factor authentication is required'));
36+
return new self(new ExceptionMessage(
37+
self::CODE_TWO_FACTOR_REQUIRED,
38+
'TWO_FACTOR_REQUIRED',
39+
'Two-factor authentication is required'
40+
));
2541
}
2642
}

src/Auth/AuthorizationException.php

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,24 @@
99

1010
final class AuthorizationException extends AbstractException
1111
{
12+
private const CODE_INSUFFICIENT_PERMISSIONS = 1101;
13+
private const CODE_ROLE_REQUIRED = 1102;
14+
1215
public static function insufficientPermissions(string $action): self
1316
{
14-
return new self(new ExceptionMessage('INSUFFICIENT_PERMISSIONS', "Insufficient permissions for action: {$action}"));
17+
return new self(new ExceptionMessage(
18+
self::CODE_INSUFFICIENT_PERMISSIONS,
19+
'INSUFFICIENT_PERMISSIONS',
20+
"Insufficient permissions for action: {$action}"
21+
));
1522
}
1623

1724
public static function roleRequired(string $role): self
1825
{
19-
return new self(new ExceptionMessage('ROLE_REQUIRED', "Required role not present: {$role}"));
26+
return new self(new ExceptionMessage(
27+
self::CODE_ROLE_REQUIRED,
28+
'ROLE_REQUIRED',
29+
"Required role not present: {$role}"
30+
));
2031
}
2132
}

src/Cache/CacheException.php

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,34 @@
99

1010
final class CacheException extends AbstractException
1111
{
12+
private const CODE_ITEM_NOT_FOUND = 1201;
13+
private const CODE_STORAGE_ERROR = 1202;
14+
private const CODE_INVALID_TTL = 1203;
15+
1216
public static function itemNotFound(string $key): self
1317
{
14-
return new self(new ExceptionMessage('CACHE_ITEM_NOT_FOUND', "Cache item not found: {$key}"));
18+
return new self(new ExceptionMessage(
19+
self::CODE_ITEM_NOT_FOUND,
20+
'CACHE_ITEM_NOT_FOUND',
21+
"Cache item not found: {$key}"
22+
));
1523
}
1624

1725
public static function storageError(string $details): self
1826
{
19-
return new self(new ExceptionMessage('CACHE_STORAGE_ERROR', "Cache storage error: {$details}"));
27+
return new self(new ExceptionMessage(
28+
self::CODE_STORAGE_ERROR,
29+
'CACHE_STORAGE_ERROR',
30+
"Cache storage error: {$details}"
31+
));
2032
}
2133

2234
public static function invalidTtl(int $ttl): self
2335
{
24-
return new self(new ExceptionMessage('INVALID_TTL', "Invalid TTL value: {$ttl}"));
36+
return new self(new ExceptionMessage(
37+
self::CODE_INVALID_TTL,
38+
'INVALID_TTL',
39+
"Invalid TTL value: {$ttl}"
40+
));
2541
}
2642
}

src/Config/ConfigurationException.php

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,34 @@
99

1010
final class ConfigurationException extends AbstractException
1111
{
12+
private const CODE_MISSING_KEY = 1301;
13+
private const CODE_INVALID_VALUE = 1302;
14+
private const CODE_ENVIRONMENT_NOT_SET = 1303;
15+
1216
public static function missingKey(string $key): self
1317
{
14-
return new self(new ExceptionMessage('MISSING_CONFIG_KEY', "Missing configuration key: {$key}"));
18+
return new self(new ExceptionMessage(
19+
self::CODE_MISSING_KEY,
20+
'MISSING_CONFIG_KEY',
21+
"Missing configuration key: {$key}"
22+
));
1523
}
1624

1725
public static function invalidValue(string $key, mixed $value): self
1826
{
19-
return new self(new ExceptionMessage('INVALID_CONFIG_VALUE', "Invalid configuration value for key '{$key}': " . var_export($value, true)));
27+
return new self(new ExceptionMessage(
28+
self::CODE_INVALID_VALUE,
29+
'INVALID_CONFIG_VALUE',
30+
"Invalid configuration value for key '{$key}': " . var_export($value, true)
31+
));
2032
}
2133

2234
public static function environmentNotSet(string $envVar): self
2335
{
24-
return new self(new ExceptionMessage('ENVIRONMENT_NOT_SET', "Environment variable not set: {$envVar}"));
36+
return new self(new ExceptionMessage(
37+
self::CODE_ENVIRONMENT_NOT_SET,
38+
'ENVIRONMENT_NOT_SET',
39+
"Environment variable not set: {$envVar}"
40+
));
2541
}
2642
}

src/Container/ContainerException.php

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,24 @@
99

1010
final class ContainerException extends AbstractException
1111
{
12+
private const CODE_SERVICE_NOT_FOUND = 1401;
13+
private const CODE_CIRCULAR_DEPENDENCY = 1402;
14+
1215
public static function serviceNotFound(string $serviceId): self
1316
{
14-
return new self(new ExceptionMessage('SERVICE_NOT_FOUND', "Service not found in container: {$serviceId}"));
17+
return new self(new ExceptionMessage(
18+
self::CODE_SERVICE_NOT_FOUND,
19+
'SERVICE_NOT_FOUND',
20+
"Service not found in container: {$serviceId}"
21+
));
1522
}
1623

1724
public static function circularDependency(string $serviceId): self
1825
{
19-
return new self(new ExceptionMessage('CIRCULAR_DEPENDENCY', "Circular dependency detected for service: {$serviceId}"));
26+
return new self(new ExceptionMessage(
27+
self::CODE_CIRCULAR_DEPENDENCY,
28+
'CIRCULAR_DEPENDENCY',
29+
"Circular dependency detected for service: {$serviceId}"
30+
));
2031
}
2132
}

src/Database/DatabaseException.php

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,34 @@
99

1010
final class DatabaseException extends AbstractException
1111
{
12+
private const CODE_CONNECTION_ERROR = 1501;
13+
private const CODE_QUERY_ERROR = 1502;
14+
private const CODE_DEADLOCK_DETECTED = 1503;
15+
1216
public static function connectionError(string $details): self
1317
{
14-
return new self(new ExceptionMessage('DB_CONNECTION_ERROR', "Database connection error: {$details}"));
18+
return new self(new ExceptionMessage(
19+
self::CODE_CONNECTION_ERROR,
20+
'DB_CONNECTION_ERROR',
21+
"Database connection error: {$details}"
22+
));
1523
}
1624

1725
public static function queryError(string $query, string $error): self
1826
{
19-
return new self(new ExceptionMessage('DB_QUERY_ERROR', "Database query error: {$error}"));
27+
return new self(new ExceptionMessage(
28+
self::CODE_QUERY_ERROR,
29+
'DB_QUERY_ERROR',
30+
"Database query error: {$error}"
31+
));
2032
}
2133

2234
public static function deadlockDetected(): self
2335
{
24-
return new self(new ExceptionMessage('DB_DEADLOCK', 'Database deadlock detected'));
36+
return new self(new ExceptionMessage(
37+
self::CODE_DEADLOCK_DETECTED,
38+
'DB_DEADLOCK',
39+
'Database deadlock detected'
40+
));
2541
}
2642
}

0 commit comments

Comments
 (0)