From 92a4a0d48130c5004261d3cb1620d43c76be5994 Mon Sep 17 00:00:00 2001 From: David Grudl Date: Thu, 26 Jan 2017 15:12:54 +0100 Subject: [PATCH] added RejectedRequestException, a descendant of BadRequestException thrown by framework [WIP] --- src/Application/Application.php | 6 ++--- src/Application/UI/Component.php | 9 ++++--- src/Application/UI/ComponentReflection.php | 10 +++---- src/Application/UI/Form.php | 2 +- src/Application/UI/Presenter.php | 15 ++++++----- src/Application/exceptions.php | 31 ++++++++++++++++++++++ 6 files changed, 53 insertions(+), 20 deletions(-) diff --git a/src/Application/Application.php b/src/Application/Application.php index 7658885c0..c5ef2db60 100644 --- a/src/Application/Application.php +++ b/src/Application/Application.php @@ -113,7 +113,7 @@ public function createInitialRequest() { $request = $this->router->match($this->httpRequest); if (!$request instanceof Request) { - throw new BadRequestException('No route for HTTP request.'); + throw new RejectedRequestException('No route for HTTP request.', RejectedRequestException::FAILED_ROUTING); } return $request; } @@ -133,13 +133,13 @@ public function processRequest(Request $request) $this->onRequest($this, $request); if (!$request->isMethod($request::FORWARD) && !strcasecmp($request->getPresenterName(), $this->errorPresenter)) { - throw new BadRequestException('Invalid request. Presenter is not achievable.'); + throw new RejectedRequestException('Invalid request. Presenter is not achievable.', RejectedRequestException::FAILED_PRESENTER); } try { $this->presenter = $this->presenterFactory->createPresenter($request->getPresenterName()); } catch (InvalidPresenterException $e) { - throw count($this->requests) > 1 ? $e : new BadRequestException($e->getMessage(), 0, $e); + throw count($this->requests) > 1 ? $e : new RejectedRequestException($e->getMessage(), RejectedRequestException::FAILED_PRESENTER, $e); } $this->onPresenter($this, $this->presenter); $response = $this->presenter->run(clone $request); diff --git a/src/Application/UI/Component.php b/src/Application/UI/Component.php index 02b71ed38..839b7278a 100644 --- a/src/Application/UI/Component.php +++ b/src/Application/UI/Component.php @@ -8,6 +8,7 @@ namespace Nette\Application\UI; use Nette; +use Nette\Application\RejectedRequestException; /** @@ -131,13 +132,13 @@ public function loadState(array $params) if (isset($params[$name])) { // NULLs are ignored $type = gettype($meta['def']); if (!$reflection->convertType($params[$name], $type)) { - throw new Nette\Application\BadRequestException(sprintf( + throw new RejectedRequestException(sprintf( "Value passed to persistent parameter '%s' in %s must be %s, %s given.", $name, $this instanceof Presenter ? 'presenter ' . $this->getName() : "component '{$this->getUniqueId()}'", $type === 'NULL' ? 'scalar' : $type, is_object($params[$name]) ? get_class($params[$name]) : gettype($params[$name]) - )); + ), RejectedRequestException::FAILED_ARGUMENT); } $this->$name = $params[$name]; } else { @@ -262,13 +263,13 @@ public static function getPersistentParams() * Calls signal handler method. * @param string * @return void - * @throws BadSignalException if there is not handler method + * @throws RejectedRequestException if there is not handler method */ public function signalReceived($signal) { if (!$this->tryCall($this->formatSignalMethod($signal), $this->params)) { $class = get_class($this); - throw new BadSignalException("There is no handler for signal '$signal' in class $class."); + throw new RejectedRequestException("There is no handler for signal '$signal' in class $class.", RejectedRequestException::FAILED_SIGNAL); } } diff --git a/src/Application/UI/ComponentReflection.php b/src/Application/UI/ComponentReflection.php index 3ae58cdea..82fb3a96b 100644 --- a/src/Application/UI/ComponentReflection.php +++ b/src/Application/UI/ComponentReflection.php @@ -8,7 +8,7 @@ namespace Nette\Application\UI; use Nette; -use Nette\Application\BadRequestException; +use Nette\Application\RejectedRequestException; use Nette\Reflection\ClassType; @@ -128,13 +128,13 @@ public static function combineArgs(\ReflectionFunctionAbstract $method, $args) if (isset($args[$name])) { $res[$i] = $args[$name]; if (!self::convertType($res[$i], $type, $isClass)) { - throw new BadRequestException(sprintf( + throw new RejectedRequestException(sprintf( 'Argument $%s passed to %s() must be %s, %s given.', $name, ($method instanceof \ReflectionMethod ? $method->getDeclaringClass()->getName() . '::' : '') . $method->getName(), $type === 'NULL' ? 'scalar' : $type, is_object($args[$name]) ? get_class($args[$name]) : gettype($args[$name]) - )); + ), $isClass ? RejectedRequestException::FAILED_OBJECT_ARGUMENT : RejectedRequestException::FAILED_ARGUMENT); } } elseif ($param->isDefaultValueAvailable()) { $res[$i] = $param->getDefaultValue(); @@ -143,11 +143,11 @@ public static function combineArgs(\ReflectionFunctionAbstract $method, $args) } elseif ($type === 'array') { $res[$i] = []; } else { - throw new BadRequestException(sprintf( + throw new RejectedRequestException(sprintf( 'Missing parameter $%s required by %s()', $name, ($method instanceof \ReflectionMethod ? $method->getDeclaringClass()->getName() . '::' : '') . $method->getName() - )); + ), $isClass ? RejectedRequestException::FAILED_OBJECT_ARGUMENT : RejectedRequestException::FAILED_ARGUMENT); } } return $res; diff --git a/src/Application/UI/Form.php b/src/Application/UI/Form.php index 27dcd479a..6bea4f7bc 100644 --- a/src/Application/UI/Form.php +++ b/src/Application/UI/Form.php @@ -143,7 +143,7 @@ public function signalReceived($signal) } } else { $class = get_class($this); - throw new BadSignalException("Missing handler for signal '$signal' in $class."); + throw new Nette\Application\RejectedRequestException("Missing handler for signal '$signal' in $class.", Nette\Application\RejectedRequestException::FAILED_SIGNAL); } } diff --git a/src/Application/UI/Presenter.php b/src/Application/UI/Presenter.php index ad8f14188..9d32246f5 100644 --- a/src/Application/UI/Presenter.php +++ b/src/Application/UI/Presenter.php @@ -11,6 +11,7 @@ use Nette\Application; use Nette\Application\Responses; use Nette\Application\Helpers; +use Nette\Application\RejectedRequestException; use Nette\Http; @@ -309,7 +310,7 @@ public function checkRequirements($element) /** * @return void - * @throws BadSignalException + * @throws RejectedRequestException */ public function processSignal() { @@ -319,10 +320,10 @@ public function processSignal() $component = $this->signalReceiver === '' ? $this : $this->getComponent($this->signalReceiver, FALSE); if ($component === NULL) { - throw new BadSignalException("The signal receiver component '$this->signalReceiver' is not found."); + throw new RejectedRequestException("The signal receiver component '$this->signalReceiver' is not found.", RejectedRequestException::FAILED_SIGNAL); } elseif (!$component instanceof ISignalReceiver) { - throw new BadSignalException("The signal receiver component '$this->signalReceiver' is not ISignalReceiver implementor."); + throw new RejectedRequestException("The signal receiver component '$this->signalReceiver' is not ISignalReceiver implementor.", RejectedRequestException::FAILED_SIGNAL); } $component->signalReceived($this->signal); @@ -393,7 +394,7 @@ public function changeAction($action) $this->view = $action; } else { - $this->error('Action name is not alphanumeric string.'); + throw new RejectedRequestException('Action name is not alphanumeric string.', RejectedRequestException::FAILED_ARGUMENT); } } @@ -444,7 +445,7 @@ public function setLayout($layout) /** * @return void - * @throws Nette\Application\BadRequestException if no template found + * @throws RejectedRequestException if no template found * @throws Nette\Application\AbortException */ public function sendTemplate() @@ -1215,7 +1216,7 @@ protected function saveGlobalState() /** * Initializes $this->globalParams, $this->signal & $this->signalReceiver, $this->action, $this->view. Called by run(). * @return void - * @throws Nette\Application\BadRequestException if action name is not valid + * @throws RejectedRequestException if action name is not valid */ private function initGlobalParameters() { @@ -1251,7 +1252,7 @@ private function initGlobalParameters() if (isset($selfParams[self::SIGNAL_KEY])) { $param = $selfParams[self::SIGNAL_KEY]; if (!is_string($param)) { - $this->error('Signal name is not string.'); + throw new RejectedRequestException('Signal name is not string.', RejectedRequestException::FAILED_ARGUMENT); } $pos = strrpos($param, '-'); if ($pos) { diff --git a/src/Application/exceptions.php b/src/Application/exceptions.php index 104481dc4..e2447ac27 100644 --- a/src/Application/exceptions.php +++ b/src/Application/exceptions.php @@ -70,3 +70,34 @@ class ForbiddenRequestException extends BadRequestException protected $code = IResponse::S403_FORBIDDEN; } + + +/** + * The exception that indicates request rejected by framework. + */ +class RejectedRequestException extends UI\BadSignalException +{ + const FAILED_ROUTING = 1; + const FAILED_PRESENTER = 2; + const FAILED_ARGUMENT = 3; + const FAILED_OBJECT_ARGUMENT = 4; + const FAILED_SIGNAL = 5; + + /** @var int */ + private $reason; + + public function __construct($message, $reason, \Exception $previous = NULL) + { + parent::__construct($message, IResponse::S404_NOT_FOUND, $previous); + } + + + /** + * @return int + */ + public function getReason() + { + return $this->reason; + } + +}