4
4
5
5
namespace SPC \exception ;
6
6
7
+ use SPC \builder \BuilderBase ;
7
8
use ZM \Logger \ConsoleColor ;
8
9
9
10
class ExceptionHandler
@@ -26,21 +27,27 @@ class ExceptionHandler
26
27
WrongUsageException::class,
27
28
];
28
29
30
+ /** @var null|BuilderBase Builder binding */
31
+ public static ?BuilderBase $ bind_builder = null ;
32
+
33
+ /** @var array<string, mixed> Build PHP extra info binding */
34
+ public static array $ bind_build_php_extra_info = [];
35
+
29
36
public static function handleSPCException (SPCException $ e ): void
30
37
{
31
38
// XXX error: yyy
32
39
$ head_msg = match ($ class = get_class ($ e )) {
33
- BuildFailureException::class => "Build failed: {$ e ->getMessage ()}" ,
34
- DownloaderException::class => "Download failed: {$ e ->getMessage ()}" ,
35
- EnvironmentException::class => "Environment check failed: {$ e ->getMessage ()}" ,
36
- ExecutionException::class => "Command execution failed: {$ e ->getMessage ()}" ,
37
- FileSystemException::class => "File system error: {$ e ->getMessage ()}" ,
40
+ BuildFailureException::class => "✗ Build failed: {$ e ->getMessage ()}" ,
41
+ DownloaderException::class => "✗ Download failed: {$ e ->getMessage ()}" ,
42
+ EnvironmentException::class => "⚠ Environment check failed: {$ e ->getMessage ()}" ,
43
+ ExecutionException::class => "✗ Command execution failed: {$ e ->getMessage ()}" ,
44
+ FileSystemException::class => "✗ File system error: {$ e ->getMessage ()}" ,
38
45
InterruptException::class => "⚠ Build interrupted by user: {$ e ->getMessage ()}" ,
39
- PatchException::class => "Patch apply failed: {$ e ->getMessage ()}" ,
40
- SPCInternalException::class => "SPC internal error: {$ e ->getMessage ()}" ,
41
- ValidationException::class => "Validation failed: {$ e ->getMessage ()}" ,
46
+ PatchException::class => "✗ Patch apply failed: {$ e ->getMessage ()}" ,
47
+ SPCInternalException::class => "✗ SPC internal error: {$ e ->getMessage ()}" ,
48
+ ValidationException::class => "⚠ Validation failed: {$ e ->getMessage ()}" ,
42
49
WrongUsageException::class => $ e ->getMessage (),
43
- default => "Unknown SPC exception {$ class }: {$ e ->getMessage ()}" ,
50
+ default => "✗ Unknown SPC exception {$ class }: {$ e ->getMessage ()}" ,
44
51
};
45
52
self ::logError ($ head_msg );
46
53
@@ -55,24 +62,24 @@ public static function handleSPCException(SPCException $e): void
55
62
56
63
// get the SPCException module
57
64
if ($ php_info = $ e ->getBuildPHPInfo ()) {
58
- self ::logError ('✗ Failed module: ' . ConsoleColor::yellow ("PHP builder { $ php_info [ ' builder_class ' ]} for {$ php_info ['os ' ]}" ));
65
+ self ::logError ('Failed module: ' . ConsoleColor::yellow ("Builder for {$ php_info ['os ' ]}" ));
59
66
} elseif ($ lib_info = $ e ->getLibraryInfo ()) {
60
- self ::logError ('✗ Failed module: ' . ConsoleColor::yellow ("library {$ lib_info ['library_name ' ]} builder for {$ lib_info ['os ' ]}" ));
67
+ self ::logError ('Failed module: ' . ConsoleColor::yellow ("library {$ lib_info ['library_name ' ]} builder for {$ lib_info ['os ' ]}" ));
61
68
} elseif ($ ext_info = $ e ->getExtensionInfo ()) {
62
- self ::logError ('✗ Failed module: ' . ConsoleColor::yellow ("shared extension {$ ext_info ['extension_name ' ]} builder " ));
69
+ self ::logError ('Failed module: ' . ConsoleColor::yellow ("shared extension {$ ext_info ['extension_name ' ]} builder " ));
63
70
} elseif (!in_array ($ class , self ::KNOWN_EXCEPTIONS )) {
64
- self ::logError ('✗ Failed From: ' . ConsoleColor::yellow ('Unknown SPC module ' . $ class ));
71
+ self ::logError ('Failed From: ' . ConsoleColor::yellow ('Unknown SPC module ' . $ class ));
65
72
}
66
- self ::logError ('' );
67
73
68
74
// get command execution info
69
75
if ($ e instanceof ExecutionException) {
70
- self ::logError ('✗ Failed command: ' . ConsoleColor::yellow ($ e ->getExecutionCommand ()));
76
+ self ::logError ('' );
77
+ self ::logError ('Failed command: ' . ConsoleColor::yellow ($ e ->getExecutionCommand ()));
71
78
if ($ cd = $ e ->getCd ()) {
72
- self ::logError ('✗ Command executed in: ' . ConsoleColor::yellow ($ cd ));
79
+ self ::logError ('Command executed in: ' . ConsoleColor::yellow ($ cd ));
73
80
}
74
81
if ($ env = $ e ->getEnv ()) {
75
- self ::logError ('✗ Command inline env variables: ' );
82
+ self ::logError ('Command inline env variables: ' );
76
83
foreach ($ env as $ k => $ v ) {
77
84
self ::logError (ConsoleColor::yellow ("{$ k }= {$ v }" ), 4 );
78
85
}
@@ -81,46 +88,42 @@ public static function handleSPCException(SPCException $e): void
81
88
82
89
// validation error
83
90
if ($ e instanceof ValidationException) {
84
- self ::logError ('✗ Failed validation module: ' . ConsoleColor::yellow ($ e ->getValidationModuleString ()));
91
+ self ::logError ('Failed validation module: ' . ConsoleColor::yellow ($ e ->getValidationModuleString ()));
85
92
}
86
93
87
94
// environment error
88
95
if ($ e instanceof EnvironmentException) {
89
- self ::logError ('✗ Failed environment check: ' . ConsoleColor::yellow ($ e ->getMessage ()));
96
+ self ::logError ('Failed environment check: ' . ConsoleColor::yellow ($ e ->getMessage ()));
90
97
if (($ solution = $ e ->getSolution ()) !== null ) {
91
- self ::logError ('✗ Solution: ' . ConsoleColor::yellow ($ solution ));
98
+ self ::logError ('Solution: ' . ConsoleColor::yellow ($ solution ));
92
99
}
93
100
}
94
101
95
102
// get patch info
96
103
if ($ e instanceof PatchException) {
97
- self ::logError ("✗ Failed patch module: {$ e ->getPatchModule ()}" );
104
+ self ::logError ("Failed patch module: {$ e ->getPatchModule ()}" );
98
105
}
99
106
100
107
// get internal trace
101
108
if ($ e instanceof SPCInternalException) {
102
- self ::logError ('✗ Internal trace: ' );
109
+ self ::logError ('Internal trace: ' );
103
110
self ::logError (ConsoleColor::gray ("{$ e ->getTraceAsString ()}\n" ), 4 );
104
111
}
105
112
106
113
// get the full build info if possible
107
- if (($ info = $ e ->getBuildPHPExtraInfo ()) && defined ('DEBUG_MODE ' )) {
108
- self ::logError ('✗ Build PHP extra info: ' );
109
- $ maxlen = 0 ;
110
- foreach ($ info as $ k => $ v ) {
111
- $ maxlen = max (strlen ($ k ), $ maxlen );
112
- }
113
- foreach ($ info as $ k => $ v ) {
114
- if (is_string ($ v )) {
115
- self ::logError ($ k . ': ' . str_pad ('' , $ maxlen - strlen ($ k )) . ConsoleColor::yellow ($ v ), 4 );
116
- } elseif (is_array ($ v ) && !is_assoc_array ($ v )) {
117
- $ first = array_shift ($ v );
118
- self ::logError ($ k . ': ' . str_pad ('' , $ maxlen - strlen ($ k )) . ConsoleColor::yellow ($ first ), 4 );
119
- foreach ($ v as $ vs ) {
120
- self ::logError (str_pad ('' , $ maxlen + 2 ) . ConsoleColor::yellow ($ vs ), 4 );
121
- }
122
- }
123
- }
114
+ if ($ info = ExceptionHandler::$ bind_build_php_extra_info ) {
115
+ self ::logError ('' , output_log: defined ('DEBUG_MODE ' ));
116
+ self ::logError ('Build PHP extra info: ' , output_log: defined ('DEBUG_MODE ' ));
117
+ self ::printArrayInfo ($ info );
118
+ }
119
+
120
+ // get the full builder options if possible
121
+ if (self ::$ bind_builder && $ e ->getBuildPHPInfo ()) {
122
+ $ info = $ e ->getBuildPHPInfo ();
123
+ self ::logError ('' , output_log: defined ('DEBUG_MODE ' ));
124
+ self ::logError ('Builder function: ' . ConsoleColor::yellow ($ info ['builder_function ' ]), output_log: defined ('DEBUG_MODE ' ));
125
+ self ::logError ('Builder options: ' , output_log: defined ('DEBUG_MODE ' ));
126
+ self ::printArrayInfo (self ::$ bind_builder ->getOptions ());
124
127
}
125
128
126
129
self ::logError ("\n---------------------------------------- \n" );
@@ -142,20 +145,57 @@ public static function handleSPCException(SPCException $e): void
142
145
public static function handleDefaultException (\Throwable $ e ): void
143
146
{
144
147
$ class = get_class ($ e );
145
- self ::logError ("Unhandled exception {$ class }: { $ e -> getMessage ()} \n\t{$ e ->getMessage ()}\n" );
148
+ self ::logError ("✗ Unhandled exception {$ class }: \n\t{$ e ->getMessage ()}\n" );
146
149
self ::logError ('Stack trace: ' );
147
- self ::logError (ConsoleColor::gray ($ e ->getTraceAsString ()), 4 );
148
- self ::logError ('Please report this exception to: https://github.com/crazywhalecc/static-php-cli/issues ' );
150
+ self ::logError (ConsoleColor::gray ($ e ->getTraceAsString ()) . PHP_EOL , 4 );
151
+ self ::logError ('⚠ Please report this exception to: https://github.com/crazywhalecc/static-php-cli/issues ' );
149
152
}
150
153
151
- private static function logError ($ message , int $ indent_space = 0 ): void
154
+ private static function logError ($ message , int $ indent_space = 0 , bool $ output_log = true ): void
152
155
{
153
156
$ spc_log = fopen (SPC_OUTPUT_LOG , 'a ' );
154
157
$ msg = explode ("\n" , (string ) $ message );
155
158
foreach ($ msg as $ v ) {
156
159
$ line = str_pad ($ v , strlen ($ v ) + $ indent_space , ' ' , STR_PAD_LEFT );
157
160
fwrite ($ spc_log , strip_ansi_colors ($ line ) . PHP_EOL );
158
- echo ConsoleColor::red ($ line ) . PHP_EOL ;
161
+ if ($ output_log ) {
162
+ echo ConsoleColor::red ($ line ) . PHP_EOL ;
163
+ }
164
+ }
165
+ }
166
+
167
+ /**
168
+ * Print array info to console and log.
169
+ */
170
+ private static function printArrayInfo (array $ info ): void
171
+ {
172
+ $ log_output = defined ('DEBUG_MODE ' );
173
+ $ maxlen = 0 ;
174
+ foreach ($ info as $ k => $ v ) {
175
+ $ maxlen = max (strlen ($ k ), $ maxlen );
176
+ }
177
+ foreach ($ info as $ k => $ v ) {
178
+ if (is_string ($ v )) {
179
+ if ($ v === '' ) {
180
+ self ::logError ($ k . ': ' . str_pad ('' , $ maxlen - strlen ($ k )) . ConsoleColor::yellow ('"" ' ), 4 , $ log_output );
181
+ } else {
182
+ self ::logError ($ k . ': ' . str_pad ('' , $ maxlen - strlen ($ k )) . ConsoleColor::yellow ($ v ), 4 , $ log_output );
183
+ }
184
+ } elseif (is_array ($ v ) && !is_assoc_array ($ v )) {
185
+ if ($ v === []) {
186
+ self ::logError ($ k . ': ' . str_pad ('' , $ maxlen - strlen ($ k )) . ConsoleColor::yellow ('[] ' ), 4 , $ log_output );
187
+ continue ;
188
+ }
189
+ $ first = array_shift ($ v );
190
+ self ::logError ($ k . ': ' . str_pad ('' , $ maxlen - strlen ($ k )) . ConsoleColor::yellow ($ first ), 4 , $ log_output );
191
+ foreach ($ v as $ vs ) {
192
+ self ::logError (str_pad ('' , $ maxlen + 2 ) . ConsoleColor::yellow ($ vs ), 4 , $ log_output );
193
+ }
194
+ } elseif (is_bool ($ v ) || is_null ($ v )) {
195
+ self ::logError ($ k . ': ' . str_pad ('' , $ maxlen - strlen ($ k )) . ConsoleColor::cyan ($ v === true ? 'true ' : ($ v === false ? 'false ' : 'null ' )), 4 , $ log_output );
196
+ } else {
197
+ self ::logError ($ k . ': ' . str_pad ('' , $ maxlen - strlen ($ k )) . ConsoleColor::yellow (json_encode ($ v , JSON_PRETTY_PRINT )), 4 , $ log_output );
198
+ }
159
199
}
160
200
}
161
201
}
0 commit comments