Skip to content

Commit

Permalink
feat(handlers): add basic Shutdown and HttpError handlers #199
Browse files Browse the repository at this point in the history
  • Loading branch information
Awilum committed Jul 30, 2021
1 parent 316f3ce commit 469d2a7
Show file tree
Hide file tree
Showing 2 changed files with 159 additions and 0 deletions.
76 changes: 76 additions & 0 deletions src/flextype/Foundation/Handlers/HttpErrorHandler.php
@@ -0,0 +1,76 @@
<?php

namespace Flextype\Foundation\Handlers;

use Psr\Http\Message\ResponseInterface;
use Slim\Exception\HttpBadRequestException;
use Slim\Exception\HttpException;
use Slim\Exception\HttpForbiddenException;
use Slim\Exception\HttpMethodNotAllowedException;
use Slim\Exception\HttpNotFoundException;
use Slim\Exception\HttpNotImplementedException;
use Slim\Exception\HttpUnauthorizedException;
use Slim\Handlers\ErrorHandler;
use Exception;
use Throwable;

class HttpErrorHandler extends ErrorHandler
{
public const BAD_REQUEST = 'BAD_REQUEST';
public const INSUFFICIENT_PRIVILEGES = 'INSUFFICIENT_PRIVILEGES';
public const NOT_ALLOWED = 'NOT_ALLOWED';
public const NOT_IMPLEMENTED = 'NOT_IMPLEMENTED';
public const RESOURCE_NOT_FOUND = 'RESOURCE_NOT_FOUND';
public const SERVER_ERROR = 'SERVER_ERROR';
public const UNAUTHENTICATED = 'UNAUTHENTICATED';

protected function respond(): ResponseInterface
{
$exception = $this->exception;
$statusCode = 500;
$type = self::SERVER_ERROR;
$description = 'An internal error has occurred while processing your request.';

if ($exception instanceof HttpException) {
$statusCode = $exception->getCode();
$description = $exception->getMessage();

if ($exception instanceof HttpNotFoundException) {
$type = self::RESOURCE_NOT_FOUND;
} elseif ($exception instanceof HttpMethodNotAllowedException) {
$type = self::NOT_ALLOWED;
} elseif ($exception instanceof HttpUnauthorizedException) {
$type = self::UNAUTHENTICATED;
} elseif ($exception instanceof HttpForbiddenException) {
$type = self::UNAUTHENTICATED;
} elseif ($exception instanceof HttpBadRequestException) {
$type = self::BAD_REQUEST;
} elseif ($exception instanceof HttpNotImplementedException) {
$type = self::NOT_IMPLEMENTED;
}
}

if (
!($exception instanceof HttpException)
&& ($exception instanceof Exception || $exception instanceof Throwable)
&& $this->displayErrorDetails
) {
$description = $exception->getMessage();
}

$error = [
'statusCode' => $statusCode,
'error' => [
'type' => $type,
'description' => $description,
],
];

$payload = json_encode($error, JSON_PRETTY_PRINT);

$response = $this->responseFactory->createResponse($statusCode);
$response->getBody()->write($payload);

return $response;
}
}
83 changes: 83 additions & 0 deletions src/flextype/Foundation/Handlers/ShutdownHandler.php
@@ -0,0 +1,83 @@
<?php

namespace Flextype\Foundation\Handlers;

use Flextype\Foundation\Handlers\HttpErrorHandler;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\Exception\HttpInternalServerErrorException;
use Slim\ResponseEmitter;

class ShutdownHandler
{
/**
* @var Request
*/
private $request;

/**
* @var HttpErrorHandler
*/
private $errorHandler;

/**
* @var bool
*/
private $displayErrorDetails;

/**
* ShutdownHandler constructor.
*
* @param Request $request
* @param HttpErrorHandler $errorHandler
* @param bool $displayErrorDetails
*/
public function __construct(Request $request, HttpErrorHandler $errorHandler, bool $displayErrorDetails) {
$this->request = $request;
$this->errorHandler = $errorHandler;
$this->displayErrorDetails = $displayErrorDetails;
}

public function __invoke()
{
$error = error_get_last();
if ($error) {
$errorFile = $error['file'];
$errorLine = $error['line'];
$errorMessage = $error['message'];
$errorType = $error['type'];
$message = 'An error while processing your request. Please try again later.';

if ($this->displayErrorDetails) {
switch ($errorType) {
case E_USER_ERROR:
$message = "FATAL ERROR: {$errorMessage}. ";
$message .= " on line {$errorLine} in file {$errorFile}.";
break;

case E_USER_WARNING:
$message = "WARNING: {$errorMessage}";
break;

case E_USER_NOTICE:
$message = "NOTICE: {$errorMessage}";
break;

default:
$message = "ERROR: {$errorMessage}";
$message .= " on line {$errorLine} in file {$errorFile}.";
break;
}
}

$exception = new HttpInternalServerErrorException($this->request, $message);
$response = $this->errorHandler->__invoke($this->request, $exception, $this->displayErrorDetails, false, false);

if (ob_get_length()) {
ob_clean();
}

$responseEmitter = new ResponseEmitter();
$responseEmitter->emit($response);
}
}
}

0 comments on commit 469d2a7

Please sign in to comment.