/** * Executes a route action, given a callable and a context. * * @param callable $targetFunc The target function to be executed. * @param Context $context The context the target function should be executed under (for dependency injection). * @return mixed The function's return value. * @throws \Exception If an exception is raised during execution, it will be rethrown. */ private function executeAction(callable $targetFunc, Context $context) { $returnValue = null; $paramValues = $context->determineParamValues($targetFunc); try { $returnValue = call_user_func_array($targetFunc, $paramValues); } catch (\Exception $ex) { $context->registerInstance($ex); $this->filters->trigger(Filters::ON_EXCEPTION, $context); if (!$this->filters->anyHandlersForEvent(Filters::ON_EXCEPTION)) { // If this exception was unhandled, rethrow it so it can be handled in the global scope throw $ex; } } return $returnValue; }
/** * Cleans the output buffer and builds a default HTTP 500 error page. * Invokes the appropriate filter if one is registered; otherwise falls back to a default message. * * @param \Exception $ex The exception we are handling. * @throws \Exception If unhandled by filters, the original exception will be rethrown. */ private function prepareErrorResponse(\Exception $ex) { ob_clean(); $this->response = new Response(); $this->response->setResponseCode(ResponseCode::HTTP_INTERNAL_SERVER_ERROR); $this->context->registerInstance($this->response); $this->context->registerInstance($ex); $rethrow = false; $this->filters->trigger(Filters::ON_EXCEPTION, $this->context); if (!$this->filters->anyHandlersForEvent(Filters::ON_EXCEPTION)) { // If this exception was completely unhandled, rethrow it so it appears as any old php exception $rethrow = true; } $this->finalizeOutputBuffer(); if (empty($this->response->getBody())) { // If nothing was output, then at least present a default message to the user. $this->serveStaticPage('error_page'); } if ($rethrow) { throw $ex; } }