/** * Dispatch middleware * * Given a route (which contains the handler for given middleware), * the $err value passed to $next, $next, and the request and response * objects, dispatch a middleware handler. * * If $err is non-falsy, and the current handler has an arity of 4, * it will be dispatched. * * If $err is falsy, and the current handler has an arity of < 4, * it will be dispatched. * * In all other cases, the handler will be ignored, and $next will be * invoked with the current $err value. * * If an exception is raised when executing the handler, the exception * will be assigned as the value of $err, and $next will be invoked * with it. * * @param Route $route * @param mixed $err * @param ServerRequestInterface $request * @param ResponseInterface $response * @param callable $next */ public function __invoke(Route $route, $err, ServerRequestInterface $request, ResponseInterface $response, callable $next) { $handler = $route->handler; $hasError = null !== $err; switch (true) { case $handler instanceof ErrorMiddlewareInterface: $arity = 4; break; case $handler instanceof MiddlewareInterface: $arity = 3; break; default: $arity = Utils::getArity($handler); break; } // @todo Trigger event with Route, original URL from request? try { if ($hasError && $arity === 4) { return $handler($err, $request, $response, $next); } if (!$hasError && $arity < 4) { return $handler($request, $response, $next); } } catch (Throwable $throwable) { return $next($request, $response, $throwable); } catch (Exception $exception) { return $next($request, $response, $exception); } return $next($request, $response, $err); }
/** * Create/update the response representing the error. * * @param Throwable|Exception $e * @param ServerRequestInterface $request * @param ResponseInterface $response * @return ResponseInterface */ public function __invoke($e, ServerRequestInterface $request, ResponseInterface $response) { $response = $response->withStatus(Utils::getStatusCode($e, $response)); $body = $response->getBody(); if ($this->isDevelopmentMode) { $escaper = new Escaper(); $body->write($escaper->escapeHtml((string) $e)); return $response; } $body->write($response->getReasonPhrase() ?: 'Unknown Error'); return $response; }
/** * Handles an error. Similar to Stratigilities except we're rendering a template. * * @param mixed $error * @param Http\Request $request * @param Http\Response $response * @return Http\Response */ private function handleError($error, Http\Request $request, Http\Response $response) { $response = $response->withStatus(Utils::getStatusCode($error, $response)); $vars = ['request' => $request, 'response' => $response]; if ($error instanceof Exception) { $vars['exception'] = $error; $vars['message'] = $error->getMessage(); } else { $vars['message'] = $error; } return $response->render('error/error', $vars); }
/** * @dataProvider nonCallables */ public function testReturnsZeroForNonCallableArguments($test) { $this->assertSame(0, Utils::getArity($test)); }
/** * Dispatch non-interop middleware. * * @param callable $middleware * @param callable $next * @param ServerRequestInterface $request * @param ResponseInterface $response * @param mixed $err * @return ResponseInterface */ private function dispatchCallableMiddleware(callable $middleware, callable $next, ServerRequestInterface $request, ResponseInterface $response, $err = null) { $hasError = null !== $err; switch (true) { case $middleware instanceof ErrorMiddlewareInterface: $arity = 4; break; case $middleware instanceof MiddlewareInterface: $arity = 3; break; default: $arity = Utils::getArity($middleware); break; } if ($this->raiseThrowables) { if ($hasError && $arity === 4) { return $middleware($err, $request, $response, $next); } if (!$hasError && $arity < 4) { return $middleware($request, $response, $next); } return $next($request, $response, $err); } try { if ($hasError && $arity === 4) { return $middleware($err, $request, $response, $next); } if (!$hasError && $arity < 4) { return $middleware($request, $response, $next); } } catch (Throwable $throwable) { return $next($request, $response, $throwable); } catch (\Exception $exception) { return $next($request, $response, $exception); } return $next($request, $response, $err); }
/** * Handle an error condition * * Use the $error to create details for the response. * * @param mixed $error * @param RequestInterface $request Request instance. * @param ResponseInterface $response Response instance. * @return Http\Response */ private function handleError($error, RequestInterface $request, ResponseInterface $response) { $response = $response->withStatus(Utils::getStatusCode($error, $response)); $message = $response->getReasonPhrase() ?: 'Unknown Error'; if (!isset($this->options['env']) || $this->options['env'] !== 'production') { $message = $this->createDevelopmentErrorMessage($error); } $response = $this->completeResponse($response, $message); $this->triggerError($error, $request, $response); return $response; }
/** * Handle an error response. * * Marshals the response status from the error. * * If the error is not an exception, it then proxies to handleError(); * otherwise, it proxies to handleException(). * * @param mixed $error * @param Request $request * @param Response $response * @return Response */ private function handleErrorResponse($error, Request $request, Response $response) { $response = $response->withStatus(Utils::getStatusCode($error, $response)); if (!$error instanceof \Exception) { return $this->handleError($error, $request, $response); } return $this->handleException($error, $request, $response); }
public function testPipeWillCreateErrorClosureForObjectImplementingHandle() { $this->markTestIncomplete(); $handler = new TestAsset\ErrorHandler(); $this->middleware->pipe($handler); $r = new ReflectionProperty($this->middleware, 'queue'); $r->setAccessible(true); $queue = $r->getValue($this->middleware); $route = $queue[$queue->count() - 1]; $this->assertInstanceOf('Zend\\Stratigility\\Route', $route); $handler = $route->handler; $this->assertInstanceOf('Closure', $handler); $this->assertEquals(4, Utils::getArity($handler)); }
/** * Is the middleware error middleware? * * @todo Remove for 2.0.0 * @param mixed $middleware * @return bool */ private function isErrorMiddleware($middleware) { return $middleware instanceof ErrorMiddlewareInterface || Utils::getArity($middleware) >= 4; }