diff --git a/.gitignore b/.gitignore index efcb7f6..93ae619 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,5 @@ composer.lock /phpunit.phar /phpunit.xml /.phpunit.cache +.phpunit.result.cache + diff --git a/composer.json b/composer.json index 861c116..eea0d3c 100644 --- a/composer.json +++ b/composer.json @@ -78,7 +78,8 @@ "source-directory": "config" }, "config-plugin": { - "di-web": "di-web.php" + "di-web": "di-web.php", + "params": "params.php" } }, "config": { diff --git a/config/di-web.php b/config/di-web.php index b6bc5d6..c2e1644 100644 --- a/config/di-web.php +++ b/config/di-web.php @@ -13,5 +13,10 @@ return [ ThrowableRendererInterface::class => HtmlRenderer::class, + HtmlRenderer::class => [ + '__construct()' => [ + 'solutionProviders' => $params['yiisoft/error-handler']['solutionProviders'], + ], + ], ThrowableResponseFactoryInterface::class => ThrowableResponseFactory::class, ]; diff --git a/config/params.php b/config/params.php new file mode 100644 index 0000000..3910dd9 --- /dev/null +++ b/config/params.php @@ -0,0 +1,16 @@ + [ + 'solutionProviders' => [ + Yiisoft\Definitions\Reference::to(Yiisoft\ErrorHandler\Solution\FriendlyExceptionSolution::class), + ], + ], +]; diff --git a/src/Renderer/HtmlRenderer.php b/src/Renderer/HtmlRenderer.php index c85acb0..ebc39fd 100644 --- a/src/Renderer/HtmlRenderer.php +++ b/src/Renderer/HtmlRenderer.php @@ -129,6 +129,7 @@ final class HtmlRenderer implements ThrowableRendererInterface * maxTraceLines?: int, * traceHeaderLine?: string, * } $settings + * @param \Yiisoft\ErrorHandler\Solution\SolutionProviderInterface[] $solutionProviders */ public function __construct( array $settings = [], @@ -137,11 +138,13 @@ public function __construct( ?int $maxSourceLines = null, ?int $maxTraceLines = null, ?string $traceHeaderLine = null, + private readonly array $solutionProviders = [] ) { $this->markdownParser = new GithubMarkdown(); $this->markdownParser->html5 = true; $this->defaultTemplatePath = dirname(__DIR__, 2) . '/templates'; + $this->template = $template ?? $settings['template'] ?? $this->defaultTemplatePath . '/production.php'; @@ -176,6 +179,7 @@ public function renderVerbose(Throwable $t, ?ServerRequestInterface $request = n $this->renderTemplate($this->verboseTemplate, [ 'request' => $request, 'throwable' => $t, + 'solutions' => $this->solutionProviders, ]), [Header::CONTENT_TYPE => self::CONTENT_TYPE], ); @@ -233,6 +237,9 @@ public function parseMarkdown(string $content): string 'ol', 'li', 'img', + 'form', + 'input', + 'button', ]); } diff --git a/src/Solution/FriendlyExceptionSolution.php b/src/Solution/FriendlyExceptionSolution.php new file mode 100644 index 0000000..4e8a302 --- /dev/null +++ b/src/Solution/FriendlyExceptionSolution.php @@ -0,0 +1,20 @@ +getSolution() !== null; + } + + public function generate(\Throwable $e): string + { + return $e->getSolution(); + } +} diff --git a/src/Solution/SolutionProviderInterface.php b/src/Solution/SolutionProviderInterface.php new file mode 100644 index 0000000..dba4c5f --- /dev/null +++ b/src/Solution/SolutionProviderInterface.php @@ -0,0 +1,22 @@ +getFirstException(); } $isFriendlyException = $throwable instanceof FriendlyExceptionInterface; -$solution = $isFriendlyException ? $throwable->getSolution() : null; $exceptionClass = get_class($throwable); $exceptionMessage = $throwable->getMessage(); @@ -92,9 +93,18 @@ htmlEncode($exceptionMessage)) ?> - -
parseMarkdown($solution) ?>
- + '; + foreach ($solutions as $i => $solution) { + if ($solution->supports($throwable)) { + echo '
'; + echo $this->parseMarkdown($solution->generate($throwable)); + echo '
'; + } + } + } + ?> renderPreviousExceptions($originalException) ?> diff --git a/tests/ConfigTest.php b/tests/ConfigTest.php index 838edf0..5554592 100644 --- a/tests/ConfigTest.php +++ b/tests/ConfigTest.php @@ -32,6 +32,9 @@ private function createContainer(?string $postfix = null): Container private function getDiConfig(?string $postfix = null): array { + $params = [ + 'yiisoft/error-handler' => ['solutionProviders' => []], + ]; return require dirname(__DIR__) . '/config/di' . ($postfix !== null ? '-' . $postfix : '') . '.php'; } }