diff --git a/framework/core/.travis.yml b/framework/core/.travis.yml index eaf4af6fd..2226ea1a2 100644 --- a/framework/core/.travis.yml +++ b/framework/core/.travis.yml @@ -1,9 +1,9 @@ language: php php: - - 5.5 - 5.6 - 7.0 + - 7.1 - hhvm matrix: diff --git a/framework/core/composer.json b/framework/core/composer.json index 9fe23f9a5..efdb49182 100644 --- a/framework/core/composer.json +++ b/framework/core/composer.json @@ -20,7 +20,7 @@ "docs": "http://flarum.org/docs" }, "require": { - "php": ">=5.5.9", + "php": ">=5.6.0", "dflydev/fig-cookies": "^1.0.2", "doctrine/dbal": "^2.5", "components/font-awesome": "^4.6", @@ -53,7 +53,7 @@ "s9e/text-formatter": "^0.8.1", "tobscure/json-api": "^0.3.0", "zendframework/zend-diactoros": "^1.1", - "zendframework/zend-stratigility": "1.2.*" + "zendframework/zend-stratigility": "^1.3" }, "require-dev": { "mockery/mockery": "^0.9.4", diff --git a/framework/core/src/Admin/Server.php b/framework/core/src/Admin/Server.php index 69b844ba3..43aa38116 100644 --- a/framework/core/src/Admin/Server.php +++ b/framework/core/src/Admin/Server.php @@ -25,11 +25,16 @@ class Server extends AbstractServer protected function getMiddleware(Application $app) { $pipe = new MiddlewarePipe; + $pipe->raiseThrowables(); if ($app->isInstalled()) { $path = parse_url($app->url('admin'), PHP_URL_PATH); $errorDir = __DIR__.'/../../error'; + // All requests should first be piped through our global error handler + $debugMode = ! $app->isUpToDate() || $app->inDebugMode(); + $pipe->pipe($path, new HandleErrors($errorDir, $app->make('log'), $debugMode)); + if ($app->isUpToDate()) { $pipe->pipe($path, $app->make('Flarum\Http\Middleware\ParseJsonBody')); $pipe->pipe($path, $app->make('Flarum\Http\Middleware\StartSession')); @@ -41,12 +46,10 @@ class Server extends AbstractServer event(new ConfigureMiddleware($pipe, $path, $this)); $pipe->pipe($path, $app->make('Flarum\Http\Middleware\DispatchRoute', ['routes' => $app->make('flarum.admin.routes')])); - $pipe->pipe($path, new HandleErrors($errorDir, $app->make('log'), $app->inDebugMode())); } else { $app->register('Flarum\Update\UpdateServiceProvider'); $pipe->pipe($path, $app->make('Flarum\Http\Middleware\DispatchRoute', ['routes' => $app->make('flarum.update.routes')])); - $pipe->pipe($path, new HandleErrors($errorDir, $app->make('log'), true)); } } diff --git a/framework/core/src/Api/Middleware/HandleErrors.php b/framework/core/src/Api/Middleware/HandleErrors.php index 58e257d6f..b650d06a5 100644 --- a/framework/core/src/Api/Middleware/HandleErrors.php +++ b/framework/core/src/Api/Middleware/HandleErrors.php @@ -11,12 +11,12 @@ namespace Flarum\Api\Middleware; +use Exception; use Flarum\Api\ErrorHandler; use Psr\Http\Message\ResponseInterface as Response; use Psr\Http\Message\ServerRequestInterface as Request; -use Zend\Stratigility\ErrorMiddlewareInterface; -class HandleErrors implements ErrorMiddlewareInterface +class HandleErrors { /** * @var ErrorHandler @@ -32,10 +32,19 @@ class HandleErrors implements ErrorMiddlewareInterface } /** - * {@inheritdoc} + * Catch all errors that happen during further middleware execution. + * + * @param Request $request + * @param Response $response + * @param callable $out + * @return Response */ - public function __invoke($e, Request $request, Response $response, callable $out = null) + public function __invoke(Request $request, Response $response, callable $out = null) { - return $this->errorHandler->handle($e); + try { + return $out($request, $response); + } catch (Exception $e) { + return $this->errorHandler->handle($e); + } } } diff --git a/framework/core/src/Api/Server.php b/framework/core/src/Api/Server.php index 59c3090f0..79dbb03b6 100644 --- a/framework/core/src/Api/Server.php +++ b/framework/core/src/Api/Server.php @@ -25,10 +25,13 @@ class Server extends AbstractServer protected function getMiddleware(Application $app) { $pipe = new MiddlewarePipe; + $pipe->raiseThrowables(); $path = parse_url($app->url('api'), PHP_URL_PATH); if ($app->isInstalled() && $app->isUpToDate()) { + $pipe->pipe($path, $app->make('Flarum\Api\Middleware\HandleErrors')); + $pipe->pipe($path, $app->make('Flarum\Http\Middleware\ParseJsonBody')); $pipe->pipe($path, $app->make('Flarum\Api\Middleware\FakeHttpMethods')); $pipe->pipe($path, $app->make('Flarum\Http\Middleware\StartSession')); @@ -40,7 +43,6 @@ class Server extends AbstractServer event(new ConfigureMiddleware($pipe, $path, $this)); $pipe->pipe($path, $app->make('Flarum\Http\Middleware\DispatchRoute', ['routes' => $app->make('flarum.api.routes')])); - $pipe->pipe($path, $app->make('Flarum\Api\Middleware\HandleErrors')); } else { $pipe->pipe($path, function () { $document = new Document; diff --git a/framework/core/src/Forum/Server.php b/framework/core/src/Forum/Server.php index ab56e6372..893ddc52c 100644 --- a/framework/core/src/Forum/Server.php +++ b/framework/core/src/Forum/Server.php @@ -26,6 +26,7 @@ class Server extends AbstractServer protected function getMiddleware(Application $app) { $pipe = new MiddlewarePipe; + $pipe->raiseThrowables(); $path = parse_url($app->url(), PHP_URL_PATH); $errorDir = __DIR__.'/../../error'; @@ -33,10 +34,13 @@ class Server extends AbstractServer if (! $app->isInstalled()) { $app->register('Flarum\Install\InstallServiceProvider'); + $pipe->pipe($path, new HandleErrors($errorDir, $app->make('log'), true)); + $pipe->pipe($path, $app->make('Flarum\Http\Middleware\StartSession')); $pipe->pipe($path, $app->make('Flarum\Http\Middleware\DispatchRoute', ['routes' => $app->make('flarum.install.routes')])); - $pipe->pipe($path, new HandleErrors($errorDir, $app->make('log'), true)); } elseif ($app->isUpToDate() && ! $app->isDownForMaintenance()) { + $pipe->pipe($path, new HandleErrors($errorDir, $app->make('log'), $app->inDebugMode())); + $pipe->pipe($path, $app->make('Flarum\Http\Middleware\ParseJsonBody')); $pipe->pipe($path, $app->make('Flarum\Http\Middleware\StartSession')); $pipe->pipe($path, $app->make('Flarum\Http\Middleware\RememberFromCookie')); @@ -46,7 +50,6 @@ class Server extends AbstractServer event(new ConfigureMiddleware($pipe, $path, $this)); $pipe->pipe($path, $app->make('Flarum\Http\Middleware\DispatchRoute', ['routes' => $app->make('flarum.forum.routes')])); - $pipe->pipe($path, new HandleErrors($errorDir, $app->make('log'), $app->inDebugMode())); } else { $pipe->pipe($path, function () use ($errorDir) { return new HtmlResponse(file_get_contents($errorDir.'/503.html', 503)); diff --git a/framework/core/src/Http/FullStackServer.php b/framework/core/src/Http/FullStackServer.php index 8da323ab2..70b331aba 100644 --- a/framework/core/src/Http/FullStackServer.php +++ b/framework/core/src/Http/FullStackServer.php @@ -26,6 +26,7 @@ class FullStackServer extends AbstractServer protected function getMiddleware(Application $app) { $pipe = new MiddlewarePipe; + $pipe->raiseThrowables(); $pipe->pipe(new ApiServer); $pipe->pipe(new AdminServer); diff --git a/framework/core/src/Http/Middleware/HandleErrors.php b/framework/core/src/Http/Middleware/HandleErrors.php index 30e6135d2..0c8897d9d 100644 --- a/framework/core/src/Http/Middleware/HandleErrors.php +++ b/framework/core/src/Http/Middleware/HandleErrors.php @@ -11,14 +11,14 @@ namespace Flarum\Http\Middleware; +use Exception; use Franzl\Middleware\Whoops\ErrorMiddleware as WhoopsMiddleware; use Psr\Http\Message\ResponseInterface as Response; use Psr\Http\Message\ServerRequestInterface as Request; use Psr\Log\LoggerInterface; use Zend\Diactoros\Response\HtmlResponse; -use Zend\Stratigility\ErrorMiddlewareInterface; -class HandleErrors implements ErrorMiddlewareInterface +class HandleErrors { /** * @var string @@ -48,9 +48,23 @@ class HandleErrors implements ErrorMiddlewareInterface } /** - * {@inheritdoc} + * Catch all errors that happen during further middleware execution. + * + * @param Request $request + * @param Response $response + * @param callable $out + * @return Response */ - public function __invoke($error, Request $request, Response $response, callable $out = null) + public function __invoke(Request $request, Response $response, callable $out = null) + { + try { + return $out($request, $response); + } catch (Exception $e) { + return $this->formatException($e); + } + } + + protected function formatException(Exception $error) { $status = 500; $errorCode = $error->getCode();