Skip to content

Enhance exception handling by binding builder and extra info to exception handler #853

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 14 commits into from
Aug 16, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
2 changes: 1 addition & 1 deletion src/SPC/builder/BuilderProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public static function makeBuilderByInput(InputInterface $input): BuilderBase
};

// bind the builder to ExceptionHandler
ExceptionHandler::$bind_builder = self::$builder;
ExceptionHandler::setBindBuilder(self::$builder);

return self::$builder;
}
Expand Down
2 changes: 1 addition & 1 deletion src/SPC/command/BuildPHPCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ public function handle(): int
$this->printFormatInfo($indent_texts);

// bind extra info to exception handler
ExceptionHandler::$bind_build_php_extra_info = $indent_texts;
ExceptionHandler::setBindBuildPhpExtraInfo($indent_texts);

logger()->notice('Build will start after 2s ...');
sleep(2);
Expand Down
41 changes: 32 additions & 9 deletions src/SPC/exception/ExceptionHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
namespace SPC\exception;

use SPC\builder\BuilderBase;
use SPC\builder\freebsd\BSDBuilder;
use SPC\builder\linux\LinuxBuilder;
use SPC\builder\macos\MacOSBuilder;
use SPC\builder\windows\WindowsBuilder;
use ZM\Logger\ConsoleColor;

class ExceptionHandler
Expand All @@ -28,10 +32,10 @@ class ExceptionHandler
];

/** @var null|BuilderBase Builder binding */
public static ?BuilderBase $bind_builder = null;
private static ?BuilderBase $bind_builder = null;

/** @var array<string, mixed> Build PHP extra info binding */
public static array $bind_build_php_extra_info = [];
private static array $bind_build_php_extra_info = [];

public static function handleSPCException(SPCException $e): void
{
Expand All @@ -47,7 +51,7 @@ public static function handleSPCException(SPCException $e): void
SPCInternalException::class => "✗ SPC internal error: {$e->getMessage()}",
ValidationException::class => "⚠ Validation failed: {$e->getMessage()}",
WrongUsageException::class => $e->getMessage(),
default => "✗Unknown SPC exception {$class}: {$e->getMessage()}",
default => "✗ Unknown SPC exception {$class}: {$e->getMessage()}",
};
self::logError($head_msg);

Expand All @@ -61,12 +65,19 @@ public static function handleSPCException(SPCException $e): void
self::logError("----------------------------------------\n");

// get the SPCException module
if ($php_info = $e->getBuildPHPInfo()) {
self::logError('Failed module: ' . ConsoleColor::yellow("Builder for {$php_info['os']}"));
} elseif ($lib_info = $e->getLibraryInfo()) {
if ($lib_info = $e->getLibraryInfo()) {
self::logError('Failed module: ' . ConsoleColor::yellow("library {$lib_info['library_name']} builder for {$lib_info['os']}"));
} elseif ($ext_info = $e->getExtensionInfo()) {
self::logError('Failed module: ' . ConsoleColor::yellow("shared extension {$ext_info['extension_name']} builder"));
} elseif (self::$bind_builder) {
$os = match (get_class(self::$bind_builder)) {
WindowsBuilder::class => 'Windows',
MacOSBuilder::class => 'macOS',
LinuxBuilder::class => 'Linux',
BSDBuilder::class => 'FreeBSD',
default => 'Unknown OS',
};
self::logError('Failed module: ' . ConsoleColor::yellow("Builder for {$os}"));
} elseif (!in_array($class, self::KNOWN_EXCEPTIONS)) {
self::logError('Failed From: ' . ConsoleColor::yellow('Unknown SPC module ' . $class));
}
Expand Down Expand Up @@ -118,12 +129,14 @@ public static function handleSPCException(SPCException $e): void
}

// get the full builder options if possible
if (self::$bind_builder && $e->getBuildPHPInfo()) {
if ($e->getBuildPHPInfo()) {
$info = $e->getBuildPHPInfo();
self::logError('', output_log: defined('DEBUG_MODE'));
self::logError('Builder function: ' . ConsoleColor::yellow($info['builder_function']), output_log: defined('DEBUG_MODE'));
self::logError('Builder options:', output_log: defined('DEBUG_MODE'));
self::printArrayInfo(self::$bind_builder->getOptions());
if (self::$bind_builder) {
self::logError('Builder options:', output_log: defined('DEBUG_MODE'));
self::printArrayInfo(self::$bind_builder->getOptions());
}
}

self::logError("\n----------------------------------------\n");
Expand Down Expand Up @@ -151,6 +164,16 @@ public static function handleDefaultException(\Throwable $e): void
self::logError('⚠ Please report this exception to: https://github.com/crazywhalecc/static-php-cli/issues');
}

public static function setBindBuilder(?BuilderBase $bind_builder): void
{
self::$bind_builder = $bind_builder;
}

public static function setBindBuildPhpExtraInfo(array $bind_build_php_extra_info): void
{
self::$bind_build_php_extra_info = $bind_build_php_extra_info;
}

private static function logError($message, int $indent_space = 0, bool $output_log = true): void
{
$spc_log = fopen(SPC_OUTPUT_LOG, 'a');
Expand Down
18 changes: 0 additions & 18 deletions src/SPC/exception/SPCException.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,11 @@
namespace SPC\exception;

use SPC\builder\BuilderBase;
use SPC\builder\freebsd\BSDBuilder;
use SPC\builder\freebsd\library\BSDLibraryBase;
use SPC\builder\LibraryBase;
use SPC\builder\linux\library\LinuxLibraryBase;
use SPC\builder\linux\LinuxBuilder;
use SPC\builder\macos\library\MacOSLibraryBase;
use SPC\builder\macos\MacOSBuilder;
use SPC\builder\windows\library\WindowsLibraryBase;
use SPC\builder\windows\WindowsBuilder;

/**
* Base class for SPC exceptions.
Expand Down Expand Up @@ -70,10 +66,7 @@ public function getLibraryInfo(): ?array
* Returns an array containing information about the PHP build process.
*
* @return null|array{
* builder_class: string,
* builder_options: array<string, mixed>,
* builder_function: string,
* os: string,
* file: null|string,
* line: null|int,
* } an array containing PHP build information
Expand Down Expand Up @@ -143,19 +136,8 @@ private function loadStackTraceInfo(): void

// Check if the class is a subclass of BuilderBase and the method is buildPHP
if (!$this->build_php_info && is_a($frame['class'], BuilderBase::class, true)) {
$options = ExceptionHandler::$bind_builder?->getOptions() ?? [];
$os = match (get_class(ExceptionHandler::$bind_builder ?? $frame['class'])) {
BSDBuilder::class => 'BSD',
LinuxBuilder::class => 'Linux',
MacOSBuilder::class => 'macOS',
WindowsBuilder::class => 'Windows',
default => 'Unknown',
};
$this->build_php_info = [
'builder_class' => $frame['class'],
'builder_options' => $options,
'builder_function' => $frame['function'],
'os' => $os,
'file' => $frame['file'] ?? null,
'line' => $frame['line'] ?? null,
];
Expand Down
Loading