Skip to content

Commit

Permalink
Removed logErrors parameter from NonFatalErrorHandlingMiddleware
Browse files Browse the repository at this point in the history
  • Loading branch information
samuelgfeller committed Apr 19, 2024
1 parent 31a23e6 commit 2ca8b76
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 37 deletions.
71 changes: 39 additions & 32 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@

This package provides an alternative to the default Slim error handler and renderer.
It renders a styled [error details page](#error-details-design) with the stack trace and the error message
or a [generic error page](#generic-error-page-design) for production.
or a [generic error page](#generic-error-page-design) for production.

Custom error page renderers can be created to change the design of the error pages
Custom error page renderers can be created to change the design of the error pages
by implementing the `ErrorDetailsPageRendererInterface`
or `GenericErrorPageRendererInterface`.

Expand All @@ -18,24 +18,25 @@ which means that it will throw exceptions with a stack trace for notices and war
development and testing like other frameworks such as Laravel or Symfony.

## Why use this package?
A reason this small library exists instead of using the default Slim error handler and a [custom
error renderer](https://www.slimframework.com/docs/v4/middleware/error-handling.html#error-handlingrendering),

A reason this small library exists instead of using the default Slim error handler and a [custom
error renderer](https://www.slimframework.com/docs/v4/middleware/error-handling.html#error-handlingrendering),
is to provide the "exception-heavy" feature and better-looking error pages.
But these things can be achieved with a custom error renderer and middleware located in the project as well.
But these things can be achieved with a custom error renderer and middleware located in the project as well.

The issue with the default `Slim\Handlers\ErrorHandler` is that while testing, the
The issue with the default `Slim\Handlers\ErrorHandler` is that while testing, the
`$contentType` in the error handler is `null` and instead of using any custom error renderer
its hardcoded to use the `Slim\Error\Renderers\HtmlErrorRenderer`. This has two consequences:
1. The error is not thrown while integration testing, which means debugging is harder.
2. Tests where an exception is expected, fail with the
[PHPUnit 11 warning](tps://github.com/sebastianbergmann/phpunit/pull/5619)
`Test code or tested code did not remove its own error handlers`.
A fix for this message is calling `restore_error_handler()` but this can't be done as the error handler doesn't
allow for custom error renderers when testing.

So a custom handler is required anyway, and with the custom renderers and the handling of
non-fatal errors, it made sense to put that in a separate small library.
1. The error is not thrown while integration testing, which means debugging is harder.
2. Tests where an exception is expected, fail with the
[PHPUnit 11 warning](tps://github.com/sebastianbergmann/phpunit/pull/5619)
`Test code or tested code did not remove its own error handlers`.
A fix for this message is calling `restore_error_handler()` but this can't be done as the error handler doesn't
allow for custom error renderers when testing.

So a custom handler is required anyway, and with the custom renderers and the handling of
non-fatal errors, it made sense to put that in a separate small library.

## Requirements

Expand Down Expand Up @@ -63,18 +64,19 @@ add the error handling middleware to
the container definitions (e.g. in the `config/container.php`) file.
The `ExceptionHandlingMiddleware` constructor accepts the following parameters:

1. Required: instance of a response factory object implementing the `ResponseFactoryInterface`
(see [here](https://github.com/samuelgfeller/slim-starter/blob/master/config/container.php) for a
default implementation of the response factory)
1. Required: instance of a response factory object implementing the
`Psr\Http\Message\ResponseFactoryInterface`
(see [here](https://github.com/samuelgfeller/slim-starter/blob/master/config/container.php) for a
default implementation of a response factory)
1. Optional: instance of a PSR 3 [logger](https://github.com/samuelgfeller/slim-example-project/wiki/Logging)
to log the error
to log the error
1. Optional: boolean to display error details
(documentation: [Error Handling](https://github.com/samuelgfeller/slim-example-project/wiki/Error-Handling))
(documentation: [Error Handling](https://github.com/samuelgfeller/slim-example-project/wiki/Error-Handling))
1. Optional: contact email for the "report error" button on the error page
1. Optional: A custom generic error page renderer that
implements `SlimErrorRenderer\Interfaces\ProdErrorPageRendererInterface`
implements `SlimErrorRenderer\Interfaces\ProdErrorPageRendererInterface`
1. Optional: A custom error details page renderer that
implements `SlimErrorRenderer\Interfaces\ErrorDetailsPageRendererInterface`
implements `SlimErrorRenderer\Interfaces\ErrorDetailsPageRendererInterface`

```php
<?php
Expand All @@ -90,8 +92,8 @@ return [

return new ExceptionHandlingMiddleware(
$app->getResponseFactory(),
$container->get(LoggerInterface::class),
(bool)$settings['error']['display_error_details'],
$settings['error']['log_errors'] ? $container->get(LoggerInterface::class) : null,
$settings['error']['display_error_details'],
$settings['public']['main_contact_email'] ?? null
);
},
Expand Down Expand Up @@ -123,13 +125,15 @@ return function (App $app) {
```

### "Exception-heavy" middleware
The `NonFatalErrorHandlingMiddleware` promotes warnings and notices to exceptions
when the `display_error_details` setting is set to `true` in the

The `NonFatalErrorHandlingMiddleware` promotes warnings and notices to exceptions
when the `display_error_details` setting is set to `true` in the
[configuration](https://github.com/samuelgfeller/slim-example-project/wiki/Configuration).
This means that the error details for notices and warnings will [be displayed](#warning--notice)
This means that the error details for notices and warnings will [be displayed](#warning--notice)
with the stack trace and error message.

#### Container instantiation

The `NonFatalErrorHandlingMiddleware` also needs to be instantiated in the container.

The constructor takes three parameters:
Expand All @@ -150,9 +154,8 @@ return [
$settings = $container->get('settings');

return new NonFatalErrorHandlingMiddleware(
(bool)$settings['error']['display_error_details'],
(bool)$settings['error']['log_warning_notice'],
$container->get(LoggerInterface::class)
$settings['error']['display_error_details'],
$settings['error']['log_errors'] ? $container->get(LoggerInterface::class) : null,
);
},

Expand All @@ -162,10 +165,11 @@ return [

#### Add to middleware stack

The middleware should be added right above the `ExceptionHandlingMiddleware` in
The middleware should be added right above the `ExceptionHandlingMiddleware` in
the stack.

File: `config/middleware.php`

```php

use Slim\App;
Expand All @@ -182,18 +186,21 @@ return function (App $app) {

### Conclusion

Have a look a the [`slim-starter`](https://github.com/samuelgfeller/slim-starter) for a default
Have a look a the [`slim-starter`](https://github.com/samuelgfeller/slim-starter) for a default
implementation of this package and the
[`slim-example-project`](https://github.com/samuelgfeller/slim-example-project) for a custom
[`slim-example-project`](https://github.com/samuelgfeller/slim-example-project) for a custom
generic error page rendering with layout.

## Error details design

### Fatal error

<img src="https://github.com/samuelgfeller/slim-example-project/assets/31797204/fea0abee-17f6-46dd-9efa-c5928244f7b6" width="600">

### Warning / Notice

<img src="https://github.com/samuelgfeller/slim-example-project/assets/31797204/9c2e3d7c-6752-4854-b535-5e54d25fd11e" width="600">

## Generic error page design

<img src="https://github.com/samuelgfeller/slim-example-project/assets/31797204/d1fd052e-a16f-4a76-895a-2eac456c4a79" width="600">
3 changes: 3 additions & 0 deletions src/Middleware/ExceptionHandlingMiddleware.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
use Throwable;

/**
* Exception handling middleware.
* Renders an error page with details or a generic error page.
*
* Documentation: https://github.com/samuelgfeller/slim-example-project/wiki/Error-Handling.
*/
final class ExceptionHandlingMiddleware implements MiddlewareInterface
Expand Down
11 changes: 6 additions & 5 deletions src/Middleware/NonFatalErrorHandlingMiddleware.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,15 @@
use Psr\Log\LoggerInterface;

/**
* Handles non-fatal errors such as warnings and notices.
* Logs non-fatal errors such as warnings and notices and
* promotes them to exceptions if "display error details" is enabled.
*
* Error handling documentation: https://github.com/samuelgfeller/slim-example-project/wiki/Error-Handling.
*/
final readonly class NonFatalErrorHandlingMiddleware implements MiddlewareInterface
{
public function __construct(
private bool $displayErrorDetails,
private bool $logErrors,
private ?LoggerInterface $logger
) {
}
Expand All @@ -43,12 +44,12 @@ function ($severity, $message, $file, $line) {
// '&' checks if a particular error level is included in the result of error_reporting().
if (error_reporting() & $severity) {
// Log non fatal errors if logging is enabled
if ($this->logErrors) {
if (isset($this->logger)) {
// If error is warning
if ($severity === E_WARNING | E_CORE_WARNING | E_COMPILE_WARNING | E_USER_WARNING) {
$this->logger?->warning("Warning [$severity] $message on line $line in file $file");
$this->logger->warning("Warning [$severity] $message on line $line in file $file");
} else { // If error is non-fatal and is not a warning
$this->logger?->notice("Notice [$severity] $message on line $line in file $file");
$this->logger->notice("Notice [$severity] $message on line $line in file $file");
}
}
if ($this->displayErrorDetails === true) {
Expand Down

0 comments on commit 2ca8b76

Please sign in to comment.