Skip to content

Commit

Permalink
New version
Browse files Browse the repository at this point in the history
  • Loading branch information
oscarotero committed Dec 16, 2017
1 parent 2f40b09 commit 2a2be7c
Show file tree
Hide file tree
Showing 7 changed files with 76 additions and 151 deletions.
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,16 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).

## [0.9.0] - 2017-12-16

### Changed

- The request handler used to generate the response must implement `Interop\Http\Server\RequestHandlerInterface`. Removed support for callables.

### Removed

- Removed `arguments()` option.

## [0.8.0] - 2017-11-13

### Changed
Expand Down Expand Up @@ -67,6 +77,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

First version

[0.9.0]: https://github.com/middlewares/error-handler/compare/v0.8.0...v0.9.0
[0.8.0]: https://github.com/middlewares/error-handler/compare/v0.7.0...v0.8.0
[0.7.0]: https://github.com/middlewares/error-handler/compare/v0.6.0...v0.7.0
[0.6.0]: https://github.com/middlewares/error-handler/compare/v0.5.0...v0.6.0
Expand Down
77 changes: 18 additions & 59 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,23 +28,29 @@ composer require middlewares/error-handler
## Example

```php
use Interop\Http\Server\RequestHandlerInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;

$handler = function (ServerRequestInterface $request) use ($logger) {
//Get the error info as an instance of Middlewares\HttpErrorException
$error = $request->getAttribute('error');
class ErrorRequestHandler implements RequestHandlerInterface
{
public function handle(ServerRequestInterface $request): ResponseInterface
{
//Get the error info as an instance of Middlewares\HttpErrorException
$error = $request->getAttribute('error');

//The error can contains context data that you can use, for example for PSR-3 loggin
$logger->error("There's an error", $error->getContext());
//The error can contains context data that you can use, for example for PSR-3 loggin
Logger::error("There's an error", $error->getContext());

//Any output is captured and added to the response's body
echo $error->getMessage();
//Any output is captured and added to the response's body
echo $error->getMessage();

return (new Response())->withStatus($error->getCode());
};
return (new Response())->withStatus($error->getCode());
}
}

$dispatcher = new Dispatcher([
new Middlewares\ErrorHandler($handler),
new Middlewares\ErrorHandler(new ErrorRequestHandler()),

function ($request, $next) {
$user = Session::signup($request);
Expand All @@ -66,31 +72,9 @@ $response = $dispatcher->dispatch(new ServerRequest());

## Options

#### `__construct(string|callable $handler = null)`

Assign the callable used to handle the error. It can be a callable or a string with the format `Class::method`. The signature of the handler is the following:

```php
use Psr\Http\Message\ServerRequestInterface;

$handler = function (ServerRequestInterface $request) {
//Get the error info using the "error" attribute
$error = $request->getAttribute('error');

//Any output is captured and added to the body stream
echo $error->getMessage();

return (new Response())->withStatus($error->getCode());
};

$dispatcher = new Dispatcher([
new Middlewares\ErrorHandler($handler)
]);

$response = $dispatcher->dispatch(new ServerRequest());
```
#### `__construct(Interop\Http\Server\RequestHandlerInterface $handler = null)`

If it's not provided, use [the default](src/ErrorHandlerDefault.php) that provides different outputs for different formats.
The request handler used to generate the response. If it's not provided, use [the default](src/ErrorHandlerDefault.php) that provides different outputs for different formats.

#### `catchExceptions(true)`

Expand All @@ -113,31 +97,6 @@ $dispatcher = new Dispatcher([

The attribute name used to store the instance of `Middlewares\HttpErrorException` with the error info in the server request. By default is `error`.

#### `arguments(...$args)`

Extra arguments to pass to the error handler. This is useful to inject, for example a logger:

```php
$handler = function (ServerRequestInterface $request, $logger) {
$error = $request->getAttribute('error');
$message = sprintf('Oops, a "%s" erro ocurried', $error->getCode());

//Log the error
$logger->error($message, $error->getContext());

//Build the response
$response = (new Response())->withStatus($error->getCode());
$response->getBody()->write($message);

return $response;
};

$dispatcher = new Dispatcher([
(new Middlewares\ErrorHandler($handler))
->arguments($logger)
]);
```

---

Please see [CHANGELOG](CHANGELOG.md) for more information about recent changes and [CONTRIBUTING](CONTRIBUTING.md) for contributing details.
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
},
"require": {
"php": "^7.0",
"middlewares/utils": "~0.13",
"middlewares/utils": "~0.14",
"http-interop/http-server-middleware": "^1.0"
},
"require-dev": {
Expand Down
28 changes: 2 additions & 26 deletions src/ErrorHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,14 @@

use Interop\Http\Server\MiddlewareInterface;
use Interop\Http\Server\RequestHandlerInterface;
use Middlewares\Utils\CallableHandler;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Throwable;

class ErrorHandler implements MiddlewareInterface
{
/**
* @var callable|string The handler used
*/
private $handler;

/**
* @var array Extra arguments passed to the handler
*/
private $arguments = [];

/**
* @var callable|null The status code validator
*/
Expand All @@ -37,12 +28,7 @@ class ErrorHandler implements MiddlewareInterface
*/
private $attribute = 'error';

/**
* Constructor.
*
* @param callable|string|null $handler
*/
public function __construct($handler = 'Middlewares\\ErrorHandlerDefault')
public function __construct(RequestHandlerInterface $handler = null)
{
$this->handler = $handler;
}
Expand Down Expand Up @@ -77,16 +63,6 @@ public function attribute(string $attribute): self
return $this;
}

/**
* Extra arguments passed to the handler.
*/
public function arguments(...$arguments): self
{
$this->arguments = $arguments;

return $this;
}

/**
* Process a server request and return a response.
*/
Expand Down Expand Up @@ -125,7 +101,7 @@ public function process(ServerRequestInterface $request, RequestHandlerInterface
private function handleError(ServerRequestInterface $request, HttpErrorException $exception): ResponseInterface
{
$request = $request->withAttribute($this->attribute, $exception);
$handler = new CallableHandler($this->handler, $this->arguments);
$handler = $this->handler ?: new ErrorHandlerDefault();

return $handler->handle($request);
}
Expand Down
73 changes: 34 additions & 39 deletions src/ErrorHandlerDefault.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@

namespace Middlewares;

use Interop\Http\Server\RequestHandlerInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;

class ErrorHandlerDefault
class ErrorHandlerDefault implements RequestHandlerInterface
{
private $handlers = [
'plain' => [
Expand Down Expand Up @@ -37,7 +38,7 @@ class ErrorHandlerDefault
/**
* Execute the error handler.
*/
public function __invoke(ServerRequestInterface $request): ResponseInterface
public function handle(ServerRequestInterface $request): ResponseInterface
{
$error = $request->getAttribute('error');
$accept = $request->getHeaderLine('Accept');
Expand All @@ -46,32 +47,32 @@ public function __invoke(ServerRequestInterface $request): ResponseInterface
foreach ($this->handlers as $method => $types) {
foreach ($types as $type) {
if (stripos($accept, $type) !== false) {
call_user_func(__CLASS__.'::'.$method, $error);
$response->getBody()->write(call_user_func(__CLASS__.'::'.$method, $error));

return $response->withHeader('Content-Type', $type);
}
}
}

static::html($error);
$response->getBody()->write(static::html($error));

return $response->withHeader('Content-Type', 'text/html');
}

/**
* Output the error as plain text.
* Return the error as plain text.
*/
public static function plain(HttpErrorException $error)
public static function plain(HttpErrorException $error): string
{
echo sprintf("Error %s\n%s", $error->getCode(), $error->getMessage());
return sprintf("Error %s\n%s", $error->getCode(), $error->getMessage());
}

/**
* Output the error as svg image.
* Return the error as svg image.
*/
public static function svg(HttpErrorException $error)
public static function svg(HttpErrorException $error): string
{
echo <<<EOT
return <<<EOT
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="50" viewBox="0 0 200 50">
<text x="20" y="30" font-family="sans-serif" title="{$error->getMessage()}">
Error {$error->getCode()}
Expand All @@ -81,11 +82,11 @@ public static function svg(HttpErrorException $error)
}

/**
* Output the error as html.
* Return the error as html.
*/
public static function html(HttpErrorException $error)
public static function html(HttpErrorException $error): string
{
echo <<<EOT
return <<<EOT
<!DOCTYPE html>
<html>
<head>
Expand All @@ -103,11 +104,11 @@ public static function html(HttpErrorException $error)
}

/**
* Output the error as json.
* Return the error as json.
*/
public static function json(HttpErrorException $error)
public static function json(HttpErrorException $error): string
{
echo json_encode([
return json_encode([
'error' => [
'code' => $error->getCode(),
'message' => $error->getMessage(),
Expand All @@ -116,11 +117,11 @@ public static function json(HttpErrorException $error)
}

/**
* Output the error as xml.
* Return the error as xml.
*/
public static function xml(HttpErrorException $error)
public static function xml(HttpErrorException $error): string
{
echo <<<EOT
return <<<EOT
<?xml version="1.0" encoding="UTF-8"?>
<error>
<code>{$error->getCode()}</code>
Expand All @@ -130,41 +131,33 @@ public static function xml(HttpErrorException $error)
}

/**
* Output the error as jpeg.
* Return the error as jpeg.
*/
public static function jpeg(HttpErrorException $error)
public static function jpeg(HttpErrorException $error): string
{
$image = self::createImage($error);

imagejpeg($image);
return self::getImage($error, 'imagejpeg');
}

/**
* Output the error as gif.
* Return the error as gif.
*/
public static function gif(HttpErrorException $error)
public static function gif(HttpErrorException $error): string
{
$image = self::createImage($error);

imagegif($image);
return self::getImage($error, 'imagegif');
}

/**
* Output the error as png.
* Return the error as png.
*/
public static function png(HttpErrorException $error)
public static function png(HttpErrorException $error): string
{
$image = self::createImage($error);

imagepng($image);
return self::getImage($error, 'imagepng');
}

/**
* Creates a image resource with the error text.
*
* @return resource
* Create and return a image as string.
*/
private static function createImage(HttpErrorException $error)
private static function getImage(HttpErrorException $error, callable $function): string
{
$size = 200;
$image = imagecreatetruecolor($size, $size);
Expand All @@ -175,6 +168,8 @@ private static function createImage(HttpErrorException $error)
imagestring($image, 5, 10, ($line * 18) + 28, $text, $textColor);
}

return $image;
ob_start();
$function($image);
return ob_get_clean();
}
}
2 changes: 1 addition & 1 deletion src/HttpErrorException.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ class HttpErrorException extends Exception
*
* @return static
*/
public static function create(int $code = 500, array $context = [], Throwable $previous = null)
public static function create(int $code = 500, array $context = [], Throwable $previous = null): self
{
if (!isset(self::$phrases[$code])) {
throw new RuntimeException("Http error not valid ({$code})");
Expand Down
Loading

0 comments on commit 2a2be7c

Please sign in to comment.