From 0ef1e416c63d665c0bc00425def2e7bf7c8010ad Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Tue, 26 Jul 2016 09:54:13 +0200 Subject: [PATCH 1/5] Created middleware to catch rest errors and return JSON responses --- .../autoload/middleware-pipeline.global.php | 6 -- .../config/middleware-pipeline.config.php | 9 +++ module/Rest/config/services.config.php | 2 + .../Error/ResponseTypeMiddleware.php | 59 +++++++++++++++++++ 4 files changed, 70 insertions(+), 6 deletions(-) create mode 100644 module/Rest/src/Middleware/Error/ResponseTypeMiddleware.php diff --git a/config/autoload/middleware-pipeline.global.php b/config/autoload/middleware-pipeline.global.php index ca116a95..6e72ea1f 100644 --- a/config/autoload/middleware-pipeline.global.php +++ b/config/autoload/middleware-pipeline.global.php @@ -26,11 +26,5 @@ return [ ], 'priority' => 1, ], - - 'error' => [ - 'middleware' => [], - 'error' => true, - 'priority' => -10000, - ], ], ]; diff --git a/module/Rest/config/middleware-pipeline.config.php b/module/Rest/config/middleware-pipeline.config.php index 78c20c38..4d908635 100644 --- a/module/Rest/config/middleware-pipeline.config.php +++ b/module/Rest/config/middleware-pipeline.config.php @@ -12,5 +12,14 @@ return [ ], 'priority' => 5, ], + + 'rest-error' => [ + 'path' => '/rest', + 'middleware' => [ + Middleware\Error\ResponseTypeMiddleware::class, + ], + 'error' => true, + 'priority' => -10000, + ], ], ]; diff --git a/module/Rest/config/services.config.php b/module/Rest/config/services.config.php index aff4cc96..44ce97f0 100644 --- a/module/Rest/config/services.config.php +++ b/module/Rest/config/services.config.php @@ -19,6 +19,8 @@ return [ Middleware\CrossDomainMiddleware::class => InvokableFactory::class, Middleware\CheckAuthenticationMiddleware::class => AnnotatedFactory::class, + + Middleware\Error\ResponseTypeMiddleware::class => AnnotatedFactory::class, ], ], diff --git a/module/Rest/src/Middleware/Error/ResponseTypeMiddleware.php b/module/Rest/src/Middleware/Error/ResponseTypeMiddleware.php new file mode 100644 index 00000000..a7e2c5e8 --- /dev/null +++ b/module/Rest/src/Middleware/Error/ResponseTypeMiddleware.php @@ -0,0 +1,59 @@ +translator = $translator; + } + + /** + * Process an incoming error, along with associated request and response. + * + * Accepts an error, a server-side request, and a response instance, and + * does something with them; if further processing can be done, it can + * delegate to `$out`. + * + * @see MiddlewareInterface + * @param mixed $error + * @param Request $request + * @param Response $response + * @param null|callable $out + * @return null|Response + */ + public function __invoke($error, Request $request, Response $response, callable $out = null) + { + $accept = $request->getHeader('Accept'); + if (! empty(array_intersect(['application/json', 'text/json', 'application/x-json'], $accept))) { + $status = $response->getStatusCode(); + $status = $status >= 400 ? $status : 500; + + return new JsonResponse([ + 'error' => RestUtils::UNKNOWN_ERROR, + 'message' => $this->translator->translate('Unknown error'), + ], $status); + } + + return $out($request, $response, $error); + } +} From 83f29080c6f179f0b1e3952b0d7948e65cfdcbd4 Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Tue, 26 Jul 2016 11:05:17 +0200 Subject: [PATCH 2/5] Improved the way rest errors are catched --- .../Error/ResponseTypeMiddleware.php | 45 ++++++++++++++++--- module/Rest/src/Util/RestUtils.php | 3 +- 2 files changed, 41 insertions(+), 7 deletions(-) diff --git a/module/Rest/src/Middleware/Error/ResponseTypeMiddleware.php b/module/Rest/src/Middleware/Error/ResponseTypeMiddleware.php index a7e2c5e8..c6319caa 100644 --- a/module/Rest/src/Middleware/Error/ResponseTypeMiddleware.php +++ b/module/Rest/src/Middleware/Error/ResponseTypeMiddleware.php @@ -45,15 +45,48 @@ class ResponseTypeMiddleware implements ErrorMiddlewareInterface { $accept = $request->getHeader('Accept'); if (! empty(array_intersect(['application/json', 'text/json', 'application/x-json'], $accept))) { - $status = $response->getStatusCode(); - $status = $status >= 400 ? $status : 500; + $status = $this->determineStatus($response); + $errorData = $this->determineErrorCode($request, $status); - return new JsonResponse([ - 'error' => RestUtils::UNKNOWN_ERROR, - 'message' => $this->translator->translate('Unknown error'), - ], $status); + return new JsonResponse($errorData, $status); } return $out($request, $response, $error); } + + /** + * @param Response $response + * @return int + */ + protected function determineStatus(Response $response) + { + $status = $response->getStatusCode(); + return $status >= 400 ? $status : 500; + } + + /** + * @param Request $request + * @param int $status + * @return string + */ + protected function determineErrorCode(Request $request, $status) + { + $errorData = $request->getAttribute('errorData'); + if (isset($errorData)) { + return $errorData; + } + + switch ($status) { + case 404: + return [ + 'error' => RestUtils::NOT_FOUND_ERROR, + 'message' => $this->translator->translate('Requested route does not exist'), + ]; + default: + return [ + 'error' => RestUtils::UNKNOWN_ERROR, + 'message' => $this->translator->translate('Unknown error occured'), + ]; + } + } } diff --git a/module/Rest/src/Util/RestUtils.php b/module/Rest/src/Util/RestUtils.php index 8e50a1cf..b67491ed 100644 --- a/module/Rest/src/Util/RestUtils.php +++ b/module/Rest/src/Util/RestUtils.php @@ -11,7 +11,8 @@ class RestUtils const INVALID_URL_ERROR = 'INVALID_URL'; const INVALID_ARGUMENT_ERROR = 'INVALID_ARGUMENT'; const INVALID_CREDENTIALS_ERROR = 'INVALID_CREDENTIALS'; - const INVALID_AUTH_TOKEN_ERROR = 'INVALID_AUTH_TOKEN_ERROR'; + const INVALID_AUTH_TOKEN_ERROR = 'INVALID_AUTH_TOKEN'; + const NOT_FOUND_ERROR = 'NOT_FOUND'; const UNKNOWN_ERROR = 'UNKNOWN_ERROR'; public static function getRestErrorCodeFromException(Common\ExceptionInterface $e) From a81dba58bd468b0494c602bfa43e612aae50f29f Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Tue, 26 Jul 2016 19:09:54 +0200 Subject: [PATCH 3/5] Defined custom NotFoundMiddleware for rest routes --- module/Core/src/Action/RedirectMiddleware.php | 4 +- .../config/middleware-pipeline.config.php | 7 +-- module/Rest/config/routes.config.php | 2 +- module/Rest/config/services.config.php | 4 +- .../CheckAuthenticationMiddleware.php | 4 +- .../src/Middleware/NotFoundMiddleware.php | 62 +++++++++++++++++++ .../{Error => }/ResponseTypeMiddleware.php | 23 ++++--- 7 files changed, 88 insertions(+), 18 deletions(-) create mode 100644 module/Rest/src/Middleware/NotFoundMiddleware.php rename module/Rest/src/Middleware/{Error => }/ResponseTypeMiddleware.php (77%) diff --git a/module/Core/src/Action/RedirectMiddleware.php b/module/Core/src/Action/RedirectMiddleware.php index 5b1907ca..1afd2d01 100644 --- a/module/Core/src/Action/RedirectMiddleware.php +++ b/module/Core/src/Action/RedirectMiddleware.php @@ -67,8 +67,8 @@ class RedirectMiddleware implements MiddlewareInterface try { $longUrl = $this->urlShortener->shortCodeToUrl($shortCode); - // If provided shortCode does not belong to a valid long URL, dispatch next middleware, which is 404 - // middleware + // If provided shortCode does not belong to a valid long URL, dispatch next middleware, which will trigger + // a not-found error if (! isset($longUrl)) { return $out($request, $response); } diff --git a/module/Rest/config/middleware-pipeline.config.php b/module/Rest/config/middleware-pipeline.config.php index 4d908635..ba228bf1 100644 --- a/module/Rest/config/middleware-pipeline.config.php +++ b/module/Rest/config/middleware-pipeline.config.php @@ -13,13 +13,12 @@ return [ 'priority' => 5, ], - 'rest-error' => [ + 'rest-not-found' => [ 'path' => '/rest', 'middleware' => [ - Middleware\Error\ResponseTypeMiddleware::class, + Middleware\NotFoundMiddleware::class, ], - 'error' => true, - 'priority' => -10000, + 'priority' => -1, ], ], ]; diff --git a/module/Rest/config/routes.config.php b/module/Rest/config/routes.config.php index 24226840..528e3011 100644 --- a/module/Rest/config/routes.config.php +++ b/module/Rest/config/routes.config.php @@ -23,7 +23,7 @@ return [ 'allowed_methods' => ['GET', 'OPTIONS'], ], [ - 'name' => 'rest-lActionist-shortened-url', + 'name' => 'rest-list-shortened-url', 'path' => '/rest/short-codes', 'middleware' => Action\ListShortcodesMiddleware::class, 'allowed_methods' => ['GET'], diff --git a/module/Rest/config/services.config.php b/module/Rest/config/services.config.php index 44ce97f0..05a1afbe 100644 --- a/module/Rest/config/services.config.php +++ b/module/Rest/config/services.config.php @@ -19,8 +19,8 @@ return [ Middleware\CrossDomainMiddleware::class => InvokableFactory::class, Middleware\CheckAuthenticationMiddleware::class => AnnotatedFactory::class, - - Middleware\Error\ResponseTypeMiddleware::class => AnnotatedFactory::class, + Middleware\ResponseTypeMiddleware::class => AnnotatedFactory::class, + Middleware\NotFoundMiddleware::class => AnnotatedFactory::class, ], ], diff --git a/module/Rest/src/Middleware/CheckAuthenticationMiddleware.php b/module/Rest/src/Middleware/CheckAuthenticationMiddleware.php index f05c1b78..1ad53c4b 100644 --- a/module/Rest/src/Middleware/CheckAuthenticationMiddleware.php +++ b/module/Rest/src/Middleware/CheckAuthenticationMiddleware.php @@ -69,7 +69,9 @@ class CheckAuthenticationMiddleware implements MiddlewareInterface // If current route is the authenticate route or an OPTIONS request, continue to the next middleware /** @var RouteResult $routeResult */ $routeResult = $request->getAttribute(RouteResult::class); - if ((isset($routeResult) && $routeResult->getMatchedRouteName() === 'rest-authenticate') + if (! isset($routeResult) + || $routeResult->isFailure() + || $routeResult->getMatchedRouteName() === 'rest-authenticate' || $request->getMethod() === 'OPTIONS' ) { return $out($request, $response); diff --git a/module/Rest/src/Middleware/NotFoundMiddleware.php b/module/Rest/src/Middleware/NotFoundMiddleware.php new file mode 100644 index 00000000..720f39ca --- /dev/null +++ b/module/Rest/src/Middleware/NotFoundMiddleware.php @@ -0,0 +1,62 @@ +translator = $translator; + } + + /** + * Process an incoming request and/or response. + * + * Accepts a server-side request and a response instance, and does + * something with them. + * + * If the response is not complete and/or further processing would not + * interfere with the work done in the middleware, or if the middleware + * wants to delegate to another process, it can use the `$out` callable + * if present. + * + * If the middleware does not return a value, execution of the current + * request is considered complete, and the response instance provided will + * be considered the response to return. + * + * Alternately, the middleware may return a response instance. + * + * Often, middleware will `return $out();`, with the assumption that a + * later middleware will return a response. + * + * @param Request $request + * @param Response $response + * @param null|callable $out + * @return null|Response + */ + public function __invoke(Request $request, Response $response, callable $out = null) + { + return new JsonResponse([ + 'error' => RestUtils::NOT_FOUND_ERROR, + 'message' => $this->translator->translate('Requested route does not exist.'), + ], 404); + } +} diff --git a/module/Rest/src/Middleware/Error/ResponseTypeMiddleware.php b/module/Rest/src/Middleware/ResponseTypeMiddleware.php similarity index 77% rename from module/Rest/src/Middleware/Error/ResponseTypeMiddleware.php rename to module/Rest/src/Middleware/ResponseTypeMiddleware.php index c6319caa..e32bef12 100644 --- a/module/Rest/src/Middleware/Error/ResponseTypeMiddleware.php +++ b/module/Rest/src/Middleware/ResponseTypeMiddleware.php @@ -1,15 +1,16 @@ getHeader('Accept'); if (! empty(array_intersect(['application/json', 'text/json', 'application/x-json'], $accept))) { - $status = $this->determineStatus($response); + $status = $this->determineStatus($request, $response); $errorData = $this->determineErrorCode($request, $status); return new JsonResponse($errorData, $status); } - return $out($request, $response, $error); + return $out($request, $response); } /** + * @param Request $request * @param Response $response * @return int */ - protected function determineStatus(Response $response) + protected function determineStatus(Request $request, Response $response) { + /** @var RouteResult $routeResult */ + $routeResult = $request->getAttribute(RouteResult::class); + if ($routeResult->isFailure()) { + return 404; + } + $status = $response->getStatusCode(); return $status >= 400 ? $status : 500; } From f3d2cf5e153024e452ea2cf4ae873e28f5583ca6 Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Tue, 26 Jul 2016 19:10:43 +0200 Subject: [PATCH 4/5] Deleted ResponseTypeMiddleware which is not ussable anymore --- module/Rest/config/services.config.php | 1 - .../src/Middleware/ResponseTypeMiddleware.php | 99 ------------------- 2 files changed, 100 deletions(-) delete mode 100644 module/Rest/src/Middleware/ResponseTypeMiddleware.php diff --git a/module/Rest/config/services.config.php b/module/Rest/config/services.config.php index 05a1afbe..b2c77bc7 100644 --- a/module/Rest/config/services.config.php +++ b/module/Rest/config/services.config.php @@ -19,7 +19,6 @@ return [ Middleware\CrossDomainMiddleware::class => InvokableFactory::class, Middleware\CheckAuthenticationMiddleware::class => AnnotatedFactory::class, - Middleware\ResponseTypeMiddleware::class => AnnotatedFactory::class, Middleware\NotFoundMiddleware::class => AnnotatedFactory::class, ], ], diff --git a/module/Rest/src/Middleware/ResponseTypeMiddleware.php b/module/Rest/src/Middleware/ResponseTypeMiddleware.php deleted file mode 100644 index e32bef12..00000000 --- a/module/Rest/src/Middleware/ResponseTypeMiddleware.php +++ /dev/null @@ -1,99 +0,0 @@ -translator = $translator; - } - - /** - * Process an incoming error, along with associated request and response. - * - * Accepts an error, a server-side request, and a response instance, and - * does something with them; if further processing can be done, it can - * delegate to `$out`. - * - * @see MiddlewareInterface - * @param Request $request - * @param Response $response - * @param null|callable $out - * @return null|Response - */ - public function __invoke(Request $request, Response $response, callable $out = null) - { - $accept = $request->getHeader('Accept'); - if (! empty(array_intersect(['application/json', 'text/json', 'application/x-json'], $accept))) { - $status = $this->determineStatus($request, $response); - $errorData = $this->determineErrorCode($request, $status); - - return new JsonResponse($errorData, $status); - } - - return $out($request, $response); - } - - /** - * @param Request $request - * @param Response $response - * @return int - */ - protected function determineStatus(Request $request, Response $response) - { - /** @var RouteResult $routeResult */ - $routeResult = $request->getAttribute(RouteResult::class); - if ($routeResult->isFailure()) { - return 404; - } - - $status = $response->getStatusCode(); - return $status >= 400 ? $status : 500; - } - - /** - * @param Request $request - * @param int $status - * @return string - */ - protected function determineErrorCode(Request $request, $status) - { - $errorData = $request->getAttribute('errorData'); - if (isset($errorData)) { - return $errorData; - } - - switch ($status) { - case 404: - return [ - 'error' => RestUtils::NOT_FOUND_ERROR, - 'message' => $this->translator->translate('Requested route does not exist'), - ]; - default: - return [ - 'error' => RestUtils::UNKNOWN_ERROR, - 'message' => $this->translator->translate('Unknown error occured'), - ]; - } - } -} From 75e744838c936b9e1e799b270916a22837cf3925 Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Wed, 27 Jul 2016 20:17:23 +0200 Subject: [PATCH 5/5] Created content based error handler which allows managing errors in a different way depending on the Accepted content type from the client --- .travis.yml | 4 ++ config/autoload/database.global.php | 2 +- config/autoload/errorhandler.local.php.dist | 14 +++- config/autoload/services.global.php | 4 +- module/Common/config/error-handler.config.php | 22 ++++++ .../Expressive/ContentBasedErrorHandler.php | 64 ++++++++++++++++++ .../ContentBasedErrorHandlerFactory.php | 30 ++++++++ .../src/Expressive/ErrorHandlerInterface.php | 18 +++++ module/Rest/config/error-handler.config.php | 18 +++++ module/Rest/lang/es.mo | Bin 1754 -> 1897 bytes module/Rest/lang/es.po | 15 ++-- .../Rest/src/Expressive/JsonErrorHandler.php | 39 +++++++++++ 12 files changed, 219 insertions(+), 11 deletions(-) create mode 100644 module/Common/config/error-handler.config.php create mode 100644 module/Common/src/Expressive/ContentBasedErrorHandler.php create mode 100644 module/Common/src/Expressive/ContentBasedErrorHandlerFactory.php create mode 100644 module/Common/src/Expressive/ErrorHandlerInterface.php create mode 100644 module/Rest/config/error-handler.config.php create mode 100644 module/Rest/src/Expressive/JsonErrorHandler.php diff --git a/.travis.yml b/.travis.yml index 905480ea..abc18f1c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,6 +11,10 @@ php: - 7.1 - hhvm +matrix: + allow_failures: + - hhvm + before_script: - composer self-update - composer install --no-interaction diff --git a/config/autoload/database.global.php b/config/autoload/database.global.php index 4e3b00e3..62733f22 100644 --- a/config/autoload/database.global.php +++ b/config/autoload/database.global.php @@ -5,7 +5,7 @@ return [ 'driver' => 'pdo_mysql', 'user' => getenv('DB_USER'), 'password' => getenv('DB_PASSWORD'), - 'dbname' => getenv('DB_NAME') ?: 'acelaya_url_shortener', + 'dbname' => getenv('DB_NAME') ?: 'shlink', 'charset' => 'utf8', 'driverOptions' => [ PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8' diff --git a/config/autoload/errorhandler.local.php.dist b/config/autoload/errorhandler.local.php.dist index 92a92497..d6de56d7 100644 --- a/config/autoload/errorhandler.local.php.dist +++ b/config/autoload/errorhandler.local.php.dist @@ -1,14 +1,14 @@ [ 'invokables' => [ 'Zend\Expressive\Whoops' => Whoops\Run::class, 'Zend\Expressive\WhoopsPageHandler' => Whoops\Handler\PrettyPageHandler::class, ], - 'factories' => [ - 'Zend\Expressive\FinalHandler' => Zend\Expressive\Container\WhoopsErrorHandlerFactory::class, - ], ], 'whoops' => [ @@ -18,4 +18,12 @@ return [ 'ajax_only' => true, ], ], + + 'error_handler' => [ + 'plugins' => [ + 'factories' => [ + ContentBasedErrorHandler::DEFAULT_CONTENT => WhoopsErrorHandlerFactory::class, + ], + ], + ], ]; diff --git a/config/autoload/services.global.php b/config/autoload/services.global.php index dc99033c..d7f56ed6 100644 --- a/config/autoload/services.global.php +++ b/config/autoload/services.global.php @@ -1,4 +1,6 @@ InvokableFactory::class, // View - 'Zend\Expressive\FinalHandler' => Container\TemplatedErrorHandlerFactory::class, + 'Zend\Expressive\FinalHandler' => ContentBasedErrorHandlerFactory::class, Template\TemplateRendererInterface::class => Twig\TwigRendererFactory::class, ], 'aliases' => [ diff --git a/module/Common/config/error-handler.config.php b/module/Common/config/error-handler.config.php new file mode 100644 index 00000000..a6165fa2 --- /dev/null +++ b/module/Common/config/error-handler.config.php @@ -0,0 +1,22 @@ + [ + 'plugins' => [ + 'invokables' => [ + 'text/plain' => FinalHandler::class, + ], + 'factories' => [ + ContentBasedErrorHandler::DEFAULT_CONTENT => TemplatedErrorHandlerFactory::class, + ], + 'aliases' => [ + 'application/xhtml+xml' => ContentBasedErrorHandler::DEFAULT_CONTENT, + ], + ], + ], + +]; diff --git a/module/Common/src/Expressive/ContentBasedErrorHandler.php b/module/Common/src/Expressive/ContentBasedErrorHandler.php new file mode 100644 index 00000000..f0d4bc04 --- /dev/null +++ b/module/Common/src/Expressive/ContentBasedErrorHandler.php @@ -0,0 +1,64 @@ +resolveErrorHandlerFromAcceptHeader($request); + return $errorHandler($request, $response, $err); + } + + /** + * Tries to resolve + * + * @param Request $request + * @return callable + */ + protected function resolveErrorHandlerFromAcceptHeader(Request $request) + { + $accepts = $request->hasHeader('Accept') ? $request->getHeaderLine('Accept') : self::DEFAULT_CONTENT; + $accepts = explode(',', $accepts); + foreach ($accepts as $accept) { + if (! $this->has($accept)) { + continue; + } + + return $this->get($accept); + } + + throw new InvalidArgumentException(sprintf( + 'It wasn\'t possible to find an error handler for ' + )); + } +} diff --git a/module/Common/src/Expressive/ContentBasedErrorHandlerFactory.php b/module/Common/src/Expressive/ContentBasedErrorHandlerFactory.php new file mode 100644 index 00000000..f262d320 --- /dev/null +++ b/module/Common/src/Expressive/ContentBasedErrorHandlerFactory.php @@ -0,0 +1,30 @@ +get('config')['error_handler']; + $plugins = isset($config['plugins']) ? $config['plugins'] : []; + return new ContentBasedErrorHandler($container, $plugins); + } +} diff --git a/module/Common/src/Expressive/ErrorHandlerInterface.php b/module/Common/src/Expressive/ErrorHandlerInterface.php new file mode 100644 index 00000000..0c787a09 --- /dev/null +++ b/module/Common/src/Expressive/ErrorHandlerInterface.php @@ -0,0 +1,18 @@ + [ + 'plugins' => [ + 'invokables' => [ + 'application/json' => JsonErrorHandler::class, + ], + 'aliases' => [ + 'application/x-json' => 'application/json', + 'text/json' => 'application/json', + ], + ], + ], + +]; diff --git a/module/Rest/lang/es.mo b/module/Rest/lang/es.mo index 2a8d4431a081c2eee3abe6973ebe7cb2bac0ce20..1bfa9aefbc137b30b9e4597348190e0ec80aacf7 100644 GIT binary patch delta 445 zcmX}nJxjwt7zgkt>6=y*;~)yHIdKuhG_=%~B4X(zln%vJ@MvzRq&ZA3pdu6}72Jv+ zz>gpu#Sb7jJ2<#GI4DjIPX3eDKHQ(*CHKN}ud^R>{kMhWEum(R9HI~dc}Aj|*N7IO z0U2C}H*gP{@C8=j5451A6Rp7m7_DExWq1dR@Btdg7qUXsCrXVDnD7xB8gL70X`&Xa z!aBT!HhhA4_zR zUxrFBM~Z-XQZaGT4U{!F)UPuYW>;(F(%@TPZH?y}cG0%8O&+MteV==Q%a!zNtnP{< z?m50>4dL=r&bImgpWVr<6E9gE+1nWw5}%rOHq51ZTE5AdA1clQ>2^C^#T|}DMtult IaFuTV0Rh5L(f|Me delta 326 zcmaFKcZ;|Fo)F7a1|Z-9Vi_RL0b*Vt-UGxS@BxU$fcPU2D*!PEBLhPZkk$m!@<4hU zkTwU>*MPJhkmh4zU{D6qwm@1ENGAemBOqN3q#pv+tOL?=K>h?4u)2DN^*{#5vdci) z3?#wIz~Bd@j{|8(AT7qmz+eERBY-r>ft^6w7)UPz(m?YVn1PrBh=JO{0BAk~P%GF& z><}RaPACo30yI=1G{{GxJh50IFTZ579Ah%$&_QlMR>^<-lwc18oB% n0|PFf#Nra&kfOxA;+({i{30ub&GVVxGH&i=&1IY{!5#\n" "Language-Team: \n" "Language: es_ES\n" "MIME-Version: 1.0\n" @@ -52,9 +52,12 @@ msgid "" "Missing or invalid auth token provided. Perform a new authentication request " "and send provided token on every new request on the \"%s\" header" msgstr "" -"No se ha proporcionado token de autenticación o este es inválido. Realia una " -"nueva petición de autenticación y envía el token proporcionado en cada nueva " -"petición en la cabecera \"%s\"" +"No se ha proporcionado token de autenticación o este es inválido. Realiza " +"una nueva petición de autenticación y envía el token proporcionado en cada " +"nueva petición en la cabecera \"%s\"" + +msgid "Requested route does not exist." +msgstr "La ruta solicitada no existe." #~ msgid "RestToken not found for token \"%s\"" #~ msgstr "No se ha encontrado un RestToken para el token \"%s\"" diff --git a/module/Rest/src/Expressive/JsonErrorHandler.php b/module/Rest/src/Expressive/JsonErrorHandler.php new file mode 100644 index 00000000..0d02c45b --- /dev/null +++ b/module/Rest/src/Expressive/JsonErrorHandler.php @@ -0,0 +1,39 @@ +getStatusCode(); + $responsePhrase = $status < 400 ? 'Internal Server Error' : $response->getReasonPhrase(); + $status = $status < 400 ? 500 : $status; + + return new JsonResponse([ + 'error' => $this->responsePhraseToCode($responsePhrase), + 'message' => $responsePhrase, + ], $status); + } + + /** + * @param string $responsePhrase + * @return string + */ + protected function responsePhraseToCode($responsePhrase) + { + return strtoupper(str_replace(' ', '_', $responsePhrase)); + } +}