Skip to content

Commit cc447a0

Browse files
committed
Refactor all exception classes, remove unclear RuntimeException, InvalidArgumentException
1 parent 0c9a302 commit cc447a0

13 files changed

+383
-19
lines changed
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace SPC\exception;
6+
7+
/**
8+
* BuildFailureException is thrown when a build process failed with other reasons.
9+
*
10+
* This exception indicates that the build operation did not complete successfully,
11+
* which may be due to various reasons such as missing built-files, incorrect configurations, etc.
12+
*/
13+
class BuildFailureException extends SPCException {}

src/SPC/exception/DownloaderException.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,10 @@
44

55
namespace SPC\exception;
66

7-
class DownloaderException extends \Exception {}
7+
/**
8+
* Exception thrown when an error occurs during the downloading process.
9+
*
10+
* This exception is used to indicate that a download operation has failed,
11+
* typically due to network issues, invalid URLs, or other related problems.
12+
*/
13+
class DownloaderException extends SPCException {}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace SPC\exception;
6+
7+
/**
8+
* EnvironmentException is thrown when there is an issue with the environment setup,
9+
* such as missing dependencies or incorrect configurations.
10+
*/
11+
class EnvironmentException extends SPCException
12+
{
13+
public function __construct(string $message, private readonly ?string $solution = null)
14+
{
15+
parent::__construct($message);
16+
}
17+
18+
/**
19+
* Returns the solution for the environment issue.
20+
*/
21+
public function getSolution(): ?string
22+
{
23+
return $this->solution;
24+
}
25+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace SPC\exception;
6+
7+
use SPC\util\shell\UnixShell;
8+
use SPC\util\shell\WindowsCmd;
9+
10+
/**
11+
* Exception thrown when an error occurs during execution of shell command.
12+
*
13+
* This exception is used to indicate that a command executed by the SPC framework
14+
* has failed, typically due to an error in the command itself or an issue with the environment
15+
* in which it was executed.
16+
*/
17+
class ExecutionException extends SPCException
18+
{
19+
public function __construct(
20+
private readonly string|UnixShell|WindowsCmd $cmd,
21+
$message = '',
22+
$code = 0,
23+
private readonly ?string $cd = null,
24+
private readonly array $env = [],
25+
?\Exception $previous = null
26+
) {
27+
parent::__construct($message, $code, $previous);
28+
}
29+
30+
/**
31+
* Returns the command that caused the execution error.
32+
*
33+
* @return string the command that was executed when the error occurred
34+
*/
35+
public function getExecutionCommand(): string
36+
{
37+
if ($this->cmd instanceof UnixShell || $this->cmd instanceof WindowsCmd) {
38+
return $this->cmd->getLastCommand();
39+
}
40+
return $this->cmd;
41+
}
42+
43+
/**
44+
* Returns the directory in which the command was executed.
45+
*/
46+
public function getCd(): ?string
47+
{
48+
return $this->cd;
49+
}
50+
51+
/**
52+
* Returns the environment variables that were set during the command execution.
53+
*/
54+
public function getEnv(): array
55+
{
56+
return $this->env;
57+
}
58+
}

src/SPC/exception/FileSystemException.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@
44

55
namespace SPC\exception;
66

7-
class FileSystemException extends \Exception {}
7+
class FileSystemException extends SPCException {}

src/SPC/exception/InterruptException.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,7 @@
44

55
namespace SPC\exception;
66

7-
class InterruptException extends \Exception {}
7+
/**
8+
* Exception caused by manual intervention.
9+
*/
10+
class InterruptException extends SPCException {}

src/SPC/exception/InvalidArgumentException.php

Lines changed: 0 additions & 7 deletions
This file was deleted.

src/SPC/exception/PatchException.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace SPC\exception;
6+
7+
/**
8+
* PatchException is thrown when there is an issue applying a patch,
9+
* such as a failure in the patch process or conflicts during patching.
10+
*/
11+
class PatchException extends SPCException
12+
{
13+
public function __construct(private readonly string $patch_module, $message, $code = 0, ?\Exception $previous = null)
14+
{
15+
parent::__construct($message, $code, $previous);
16+
}
17+
18+
/**
19+
* Returns the name of the patch module that caused the exception.
20+
*/
21+
public function getPatchModule(): string
22+
{
23+
return $this->patch_module;
24+
}
25+
}

src/SPC/exception/RuntimeException.php

Lines changed: 0 additions & 7 deletions
This file was deleted.

src/SPC/exception/SPCException.php

Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace SPC\exception;
6+
7+
use SPC\builder\BuilderBase;
8+
use SPC\builder\freebsd\BSDBuilder;
9+
use SPC\builder\freebsd\library\BSDLibraryBase;
10+
use SPC\builder\LibraryBase;
11+
use SPC\builder\linux\library\LinuxLibraryBase;
12+
use SPC\builder\linux\LinuxBuilder;
13+
use SPC\builder\macos\library\MacOSLibraryBase;
14+
use SPC\builder\macos\MacOSBuilder;
15+
use SPC\builder\windows\library\WindowsLibraryBase;
16+
use SPC\builder\windows\WindowsBuilder;
17+
18+
/**
19+
* Base class for SPC exceptions.
20+
*
21+
* This class serves as the base for all exceptions thrown by the SPC framework.
22+
* It extends the built-in PHP Exception class, allowing for custom exception handling
23+
* and categorization of SPC-related errors.
24+
*/
25+
abstract class SPCException extends \Exception
26+
{
27+
private static ?array $build_php_extra_info = null;
28+
29+
private ?array $library_info = null;
30+
31+
private ?array $extension_info = null;
32+
33+
private ?array $build_php_info = null;
34+
35+
private array $extra_log_files = [];
36+
37+
public function __construct(string $message = '', int $code = 0, ?\Throwable $previous = null)
38+
{
39+
parent::__construct($message, $code, $previous);
40+
$this->loadStackTraceInfo();
41+
}
42+
43+
public static function bindBuildPHPExtraInfo(array $indent_texts): void
44+
{
45+
self::$build_php_extra_info = $indent_texts;
46+
}
47+
48+
public function bindExtensionInfo(array $extension_info): void
49+
{
50+
$this->extension_info = $extension_info;
51+
}
52+
53+
public function addExtraLogFile(string $key, string $filename): void
54+
{
55+
$this->extra_log_files[$key] = $filename;
56+
}
57+
58+
public function getBuildPHPExtraInfo(): ?array
59+
{
60+
return self::$build_php_extra_info;
61+
}
62+
63+
/**
64+
* Returns an array containing information about the SPC module.
65+
*
66+
* This method can be overridden by subclasses to provide specific module information.
67+
*
68+
* @return null|array{
69+
* library_name: string,
70+
* library_class: string,
71+
* os: string,
72+
* file: null|string,
73+
* line: null|int,
74+
* } an array containing module information
75+
*/
76+
public function getLibraryInfo(): ?array
77+
{
78+
return $this->library_info;
79+
}
80+
81+
/**
82+
* Returns an array containing information about the PHP build process.
83+
*
84+
* @return null|array{
85+
* builder_class: string,
86+
* os: string,
87+
* file: null|string,
88+
* line: null|int,
89+
* } an array containing PHP build information
90+
*/
91+
public function getBuildPHPInfo(): ?array
92+
{
93+
return $this->build_php_info;
94+
}
95+
96+
/**
97+
* Returns an array containing information about the SPC extension.
98+
*
99+
* This method can be overridden by subclasses to provide specific extension information.
100+
*
101+
* @return null|array{
102+
* extension_name: string,
103+
* extension_class: string,
104+
* file: null|string,
105+
* line: null|int,
106+
* } an array containing extension information
107+
*/
108+
public function getExtensionInfo(): ?array
109+
{
110+
return $this->extension_info;
111+
}
112+
113+
public function getExtraLogFiles(): array
114+
{
115+
return $this->extra_log_files;
116+
}
117+
118+
private function loadStackTraceInfo(): void
119+
{
120+
$trace = $this->getTrace();
121+
foreach ($trace as $frame) {
122+
if (!isset($frame['class'])) {
123+
continue;
124+
}
125+
126+
// Check if the class is a subclass of LibraryBase
127+
if (!$this->library_info && is_subclass_of($frame['class'], LibraryBase::class)) {
128+
try {
129+
$reflection = new \ReflectionClass($frame['class']);
130+
if ($reflection->hasConstant('NAME')) {
131+
$name = $reflection->getConstant('NAME');
132+
if ($name !== 'unknown') {
133+
$this->library_info = [
134+
'library_name' => $name,
135+
'library_class' => $frame['class'],
136+
'os' => match (true) {
137+
is_a($frame['class'], BSDLibraryBase::class, true) => 'BSD',
138+
is_a($frame['class'], LinuxLibraryBase::class, true) => 'Linux',
139+
is_a($frame['class'], MacOSLibraryBase::class, true) => 'macOS',
140+
is_a($frame['class'], WindowsLibraryBase::class, true) => 'Windows',
141+
default => 'Unknown',
142+
},
143+
'file' => $frame['file'] ?? null,
144+
'line' => $frame['line'] ?? null,
145+
];
146+
continue;
147+
}
148+
}
149+
} catch (\ReflectionException) {
150+
continue;
151+
}
152+
}
153+
154+
// Check if the class is a subclass of BuilderBase and the method is buildPHP
155+
if (!$this->build_php_info && is_subclass_of($frame['class'], BuilderBase::class) && $frame['function'] === 'buildPHP') {
156+
$reflection = new \ReflectionClass($frame['class']);
157+
if ($reflection->hasProperty('options')) {
158+
$options = $reflection->getProperty('options')->getValue();
159+
}
160+
$this->build_php_info = [
161+
'builder_class' => $frame['class'],
162+
'builder_options' => $options ?? [],
163+
'os' => match (true) {
164+
is_a($frame['class'], BSDBuilder::class, true) => 'BSD',
165+
is_a($frame['class'], LinuxBuilder::class, true) => 'Linux',
166+
is_a($frame['class'], MacOSBuilder::class, true) => 'macOS',
167+
is_a($frame['class'], WindowsBuilder::class, true) => 'Windows',
168+
default => 'Unknown',
169+
},
170+
'file' => $frame['file'] ?? null,
171+
'line' => $frame['line'] ?? null,
172+
];
173+
}
174+
}
175+
}
176+
}

0 commit comments

Comments
 (0)