diff --git a/src/Application/MicroPresenter.php b/src/Application/MicroPresenter.php index a5404213e..80dd13e45 100644 --- a/src/Application/MicroPresenter.php +++ b/src/Application/MicroPresenter.php @@ -80,7 +80,11 @@ public function run(Application\Request $request): Application\IResponse } } $params['presenter'] = $this; - $params = Application\UI\ComponentReflection::combineArgs($reflection, $params); + try { + $params = Application\UI\ComponentReflection::combineArgs($reflection, $params); + } catch (Nette\InvalidArgumentException $e) { + $this->error($e->getMessage()); + } $response = $callback(...array_values($params)); diff --git a/src/Application/UI/Component.php b/src/Application/UI/Component.php index 2d58b347a..5c3aa0153 100644 --- a/src/Application/UI/Component.php +++ b/src/Application/UI/Component.php @@ -82,7 +82,12 @@ protected function tryCall(string $method, array $params): bool $rm = $rc->getMethod($method); if ($rm->isPublic() && !$rm->isAbstract() && !$rm->isStatic()) { $this->checkRequirements($rm); - $rm->invokeArgs($this, $rc->combineArgs($rm, $params)); + try { + $args = $rc->combineArgs($rm, $params); + } catch (Nette\InvalidArgumentException $e) { + throw new Nette\Application\BadRequestException($e->getMessage()); + } + $rm->invokeArgs($this, $args); return TRUE; } } diff --git a/src/Application/UI/ComponentReflection.php b/src/Application/UI/ComponentReflection.php index 56fa67a3a..22ebad5de 100644 --- a/src/Application/UI/ComponentReflection.php +++ b/src/Application/UI/ComponentReflection.php @@ -10,7 +10,6 @@ namespace Nette\Application\UI; use Nette; -use Nette\Application\BadRequestException; /** @@ -116,7 +115,7 @@ 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 Nette\InvalidArgumentException(sprintf( 'Argument $%s passed to %s() must be %s, %s given.', $name, ($method instanceof \ReflectionMethod ? $method->getDeclaringClass()->getName() . '::' : '') . $method->getName(), @@ -131,7 +130,7 @@ public static function combineArgs(\ReflectionFunctionAbstract $method, $args): } elseif ($type === 'array') { $res[$i] = []; } else { - throw new BadRequestException(sprintf( + throw new Nette\InvalidArgumentException(sprintf( 'Missing parameter $%s required by %s()', $name, ($method instanceof \ReflectionMethod ? $method->getDeclaringClass()->getName() . '::' : '') . $method->getName() diff --git a/tests/UI/ComponentReflection.combineArgs.php7.phpt b/tests/UI/ComponentReflection.combineArgs.php7.phpt index 4a75121dc..8ec1c08c3 100644 --- a/tests/UI/ComponentReflection.combineArgs.php7.phpt +++ b/tests/UI/ComponentReflection.combineArgs.php7.phpt @@ -7,7 +7,6 @@ declare(strict_types=1); use Nette\Application\UI\ComponentReflection as Reflection; -use Nette\Application\BadRequestException; use Tester\Assert; require __DIR__ . '/../bootstrap.php'; @@ -54,7 +53,7 @@ test(function () { Assert::exception(function () use ($method) { Reflection::combineArgs($method, ['int' => []]); - }, BadRequestException::class, 'Argument $int passed to MyPresenter::params() must be scalar, array given.'); + }, Nette\InvalidArgumentException::class, 'Argument $int passed to MyPresenter::params() must be scalar, array given.'); }); @@ -66,31 +65,31 @@ test(function () { Assert::exception(function () use ($method) { Reflection::combineArgs($method, []); - }, BadRequestException::class, 'Missing parameter $int required by MyPresenter::hints()'); + }, Nette\InvalidArgumentException::class, 'Missing parameter $int required by MyPresenter::hints()'); Assert::exception(function () use ($method) { Reflection::combineArgs($method, ['int' => '']); - }, BadRequestException::class, 'Argument $int passed to MyPresenter::hints() must be int, string given.'); + }, Nette\InvalidArgumentException::class, 'Argument $int passed to MyPresenter::hints() must be int, string given.'); Assert::exception(function () use ($method) { Reflection::combineArgs($method, ['int' => NULL]); - }, BadRequestException::class, 'Missing parameter $int required by MyPresenter::hints()'); + }, Nette\InvalidArgumentException::class, 'Missing parameter $int required by MyPresenter::hints()'); Assert::exception(function () use ($method) { Reflection::combineArgs($method, ['int' => new stdClass]); - }, BadRequestException::class, 'Argument $int passed to MyPresenter::hints() must be int, stdClass given.'); + }, Nette\InvalidArgumentException::class, 'Argument $int passed to MyPresenter::hints() must be int, stdClass given.'); Assert::exception(function () use ($method) { Reflection::combineArgs($method, ['int' => []]); - }, BadRequestException::class, 'Argument $int passed to MyPresenter::hints() must be int, array given.'); + }, Nette\InvalidArgumentException::class, 'Argument $int passed to MyPresenter::hints() must be int, array given.'); Assert::exception(function () use ($method) { Reflection::combineArgs($method, ['int' => '1', 'bool' => '']); - }, BadRequestException::class, 'Argument $bool passed to MyPresenter::hints() must be bool, string given.'); + }, Nette\InvalidArgumentException::class, 'Argument $bool passed to MyPresenter::hints() must be bool, string given.'); Assert::exception(function () use ($method) { Reflection::combineArgs($method, ['int' => '1', 'bool' => '1', 'str' => '', 'arr' => '']); - }, BadRequestException::class, 'Argument $arr passed to MyPresenter::hints() must be array, string given.'); + }, Nette\InvalidArgumentException::class, 'Argument $arr passed to MyPresenter::hints() must be array, string given.'); }); @@ -104,23 +103,23 @@ test(function () { Assert::exception(function () use ($method) { Reflection::combineArgs($method, ['int' => '']); - }, BadRequestException::class, 'Argument $int passed to MyPresenter::hintsNulls() must be int, string given.'); + }, Nette\InvalidArgumentException::class, 'Argument $int passed to MyPresenter::hintsNulls() must be int, string given.'); Assert::exception(function () use ($method) { Reflection::combineArgs($method, ['int' => new stdClass]); - }, BadRequestException::class, 'Argument $int passed to MyPresenter::hintsNulls() must be int, stdClass given.'); + }, Nette\InvalidArgumentException::class, 'Argument $int passed to MyPresenter::hintsNulls() must be int, stdClass given.'); Assert::exception(function () use ($method) { Reflection::combineArgs($method, ['int' => []]); - }, BadRequestException::class, 'Argument $int passed to MyPresenter::hintsNulls() must be int, array given.'); + }, Nette\InvalidArgumentException::class, 'Argument $int passed to MyPresenter::hintsNulls() must be int, array given.'); Assert::exception(function () use ($method) { Reflection::combineArgs($method, ['int' => '1', 'bool' => '']); - }, BadRequestException::class, 'Argument $bool passed to MyPresenter::hintsNulls() must be bool, string given.'); + }, Nette\InvalidArgumentException::class, 'Argument $bool passed to MyPresenter::hintsNulls() must be bool, string given.'); Assert::exception(function () use ($method) { Reflection::combineArgs($method, ['int' => '1', 'bool' => '1', 'str' => '', 'arr' => '']); - }, BadRequestException::class, 'Argument $arr passed to MyPresenter::hintsNulls() must be array, string given.'); + }, Nette\InvalidArgumentException::class, 'Argument $arr passed to MyPresenter::hintsNulls() must be array, string given.'); }); @@ -134,23 +133,23 @@ test(function () { Assert::exception(function () use ($method) { Reflection::combineArgs($method, ['int' => '']); - }, BadRequestException::class, 'Argument $int passed to MyPresenter::hintsDefaults() must be int, string given.'); + }, Nette\InvalidArgumentException::class, 'Argument $int passed to MyPresenter::hintsDefaults() must be int, string given.'); Assert::exception(function () use ($method) { Reflection::combineArgs($method, ['int' => new stdClass]); - }, BadRequestException::class, 'Argument $int passed to MyPresenter::hintsDefaults() must be int, stdClass given.'); + }, Nette\InvalidArgumentException::class, 'Argument $int passed to MyPresenter::hintsDefaults() must be int, stdClass given.'); Assert::exception(function () use ($method) { Reflection::combineArgs($method, ['int' => []]); - }, BadRequestException::class, 'Argument $int passed to MyPresenter::hintsDefaults() must be int, array given.'); + }, Nette\InvalidArgumentException::class, 'Argument $int passed to MyPresenter::hintsDefaults() must be int, array given.'); Assert::exception(function () use ($method) { Reflection::combineArgs($method, ['int' => '1', 'bool' => '']); - }, BadRequestException::class, 'Argument $bool passed to MyPresenter::hintsDefaults() must be bool, string given.'); + }, Nette\InvalidArgumentException::class, 'Argument $bool passed to MyPresenter::hintsDefaults() must be bool, string given.'); Assert::exception(function () use ($method) { Reflection::combineArgs($method, ['int' => '1', 'bool' => '1', 'str' => '', 'arr' => '']); - }, BadRequestException::class, 'Argument $arr passed to MyPresenter::hintsDefaults() must be array, string given.'); + }, Nette\InvalidArgumentException::class, 'Argument $arr passed to MyPresenter::hintsDefaults() must be array, string given.'); }); @@ -164,23 +163,23 @@ test(function () { Assert::exception(function () use ($method) { Reflection::combineArgs($method, ['int' => '']); - }, BadRequestException::class, 'Argument $int passed to MyPresenter::defaults() must be integer, string given.'); + }, Nette\InvalidArgumentException::class, 'Argument $int passed to MyPresenter::defaults() must be integer, string given.'); Assert::exception(function () use ($method) { Reflection::combineArgs($method, ['int' => new stdClass]); - }, BadRequestException::class, 'Argument $int passed to MyPresenter::defaults() must be integer, stdClass given.'); + }, Nette\InvalidArgumentException::class, 'Argument $int passed to MyPresenter::defaults() must be integer, stdClass given.'); Assert::exception(function () use ($method) { Reflection::combineArgs($method, ['int' => []]); - }, BadRequestException::class, 'Argument $int passed to MyPresenter::defaults() must be integer, array given.'); + }, Nette\InvalidArgumentException::class, 'Argument $int passed to MyPresenter::defaults() must be integer, array given.'); Assert::exception(function () use ($method) { Reflection::combineArgs($method, ['int' => '1', 'bool' => '']); - }, BadRequestException::class, 'Argument $bool passed to MyPresenter::defaults() must be boolean, string given.'); + }, Nette\InvalidArgumentException::class, 'Argument $bool passed to MyPresenter::defaults() must be boolean, string given.'); Assert::exception(function () use ($method) { Reflection::combineArgs($method, ['int' => '1', 'bool' => '1', 'str' => '', 'arr' => '']); - }, BadRequestException::class, 'Argument $arr passed to MyPresenter::defaults() must be array, string given.'); + }, Nette\InvalidArgumentException::class, 'Argument $arr passed to MyPresenter::defaults() must be array, string given.'); }); @@ -191,17 +190,17 @@ test(function () { Assert::exception(function () use ($method) { Reflection::combineArgs($method, []); - }, BadRequestException::class, 'Missing parameter $req required by MyPresenter::objects()'); + }, Nette\InvalidArgumentException::class, 'Missing parameter $req required by MyPresenter::objects()'); Assert::exception(function () use ($method) { Reflection::combineArgs($method, ['req' => NULL, 'opt' => NULL]); - }, BadRequestException::class, 'Missing parameter $req required by MyPresenter::objects()'); + }, Nette\InvalidArgumentException::class, 'Missing parameter $req required by MyPresenter::objects()'); Assert::exception(function () use ($method) { Reflection::combineArgs($method, ['req' => $method, 'opt' => NULL]); - }, BadRequestException::class, 'Argument $req passed to MyPresenter::objects() must be stdClass, ReflectionMethod given.'); + }, Nette\InvalidArgumentException::class, 'Argument $req passed to MyPresenter::objects() must be stdClass, ReflectionMethod given.'); Assert::exception(function () use ($method) { Reflection::combineArgs($method, ['req' => [], 'opt' => NULL]); - }, BadRequestException::class, 'Argument $req passed to MyPresenter::objects() must be stdClass, array given.'); + }, Nette\InvalidArgumentException::class, 'Argument $req passed to MyPresenter::objects() must be stdClass, array given.'); }); diff --git a/tests/UI/ComponentReflection.combineArgs.php71.phpt b/tests/UI/ComponentReflection.combineArgs.php71.phpt index aa1887cbc..b7570347b 100644 --- a/tests/UI/ComponentReflection.combineArgs.php71.phpt +++ b/tests/UI/ComponentReflection.combineArgs.php71.phpt @@ -8,7 +8,6 @@ declare(strict_types=1); use Nette\Application\UI\ComponentReflection as Reflection; -use Nette\Application\BadRequestException; use Tester\Assert; require __DIR__ . '/../bootstrap.php'; @@ -55,7 +54,7 @@ test(function () { Assert::exception(function () use ($method) { Reflection::combineArgs($method, ['int' => []]); - }, BadRequestException::class, 'Argument $int passed to MyPresenter::params() must be scalar, array given.'); + }, Nette\InvalidArgumentException::class, 'Argument $int passed to MyPresenter::params() must be scalar, array given.'); }); @@ -67,31 +66,31 @@ test(function () { Assert::exception(function () use ($method) { Reflection::combineArgs($method, []); - }, BadRequestException::class, 'Missing parameter $int required by MyPresenter::hints()'); + }, Nette\InvalidArgumentException::class, 'Missing parameter $int required by MyPresenter::hints()'); Assert::exception(function () use ($method) { Reflection::combineArgs($method, ['int' => '']); - }, BadRequestException::class, 'Argument $int passed to MyPresenter::hints() must be int, string given.'); + }, Nette\InvalidArgumentException::class, 'Argument $int passed to MyPresenter::hints() must be int, string given.'); Assert::exception(function () use ($method) { Reflection::combineArgs($method, ['int' => NULL]); - }, BadRequestException::class, 'Missing parameter $int required by MyPresenter::hints()'); + }, Nette\InvalidArgumentException::class, 'Missing parameter $int required by MyPresenter::hints()'); Assert::exception(function () use ($method) { Reflection::combineArgs($method, ['int' => new stdClass]); - }, BadRequestException::class, 'Argument $int passed to MyPresenter::hints() must be int, stdClass given.'); + }, Nette\InvalidArgumentException::class, 'Argument $int passed to MyPresenter::hints() must be int, stdClass given.'); Assert::exception(function () use ($method) { Reflection::combineArgs($method, ['int' => []]); - }, BadRequestException::class, 'Argument $int passed to MyPresenter::hints() must be int, array given.'); + }, Nette\InvalidArgumentException::class, 'Argument $int passed to MyPresenter::hints() must be int, array given.'); Assert::exception(function () use ($method) { Reflection::combineArgs($method, ['int' => '1', 'bool' => '']); - }, BadRequestException::class, 'Argument $bool passed to MyPresenter::hints() must be bool, string given.'); + }, Nette\InvalidArgumentException::class, 'Argument $bool passed to MyPresenter::hints() must be bool, string given.'); Assert::exception(function () use ($method) { Reflection::combineArgs($method, ['int' => '1', 'bool' => '1', 'str' => '', 'arr' => '']); - }, BadRequestException::class, 'Argument $arr passed to MyPresenter::hints() must be array, string given.'); + }, Nette\InvalidArgumentException::class, 'Argument $arr passed to MyPresenter::hints() must be array, string given.'); }); @@ -105,23 +104,23 @@ test(function () { Assert::exception(function () use ($method) { Reflection::combineArgs($method, ['int' => '']); - }, BadRequestException::class, 'Argument $int passed to MyPresenter::hintsNulls() must be int, string given.'); + }, Nette\InvalidArgumentException::class, 'Argument $int passed to MyPresenter::hintsNulls() must be int, string given.'); Assert::exception(function () use ($method) { Reflection::combineArgs($method, ['int' => new stdClass]); - }, BadRequestException::class, 'Argument $int passed to MyPresenter::hintsNulls() must be int, stdClass given.'); + }, Nette\InvalidArgumentException::class, 'Argument $int passed to MyPresenter::hintsNulls() must be int, stdClass given.'); Assert::exception(function () use ($method) { Reflection::combineArgs($method, ['int' => []]); - }, BadRequestException::class, 'Argument $int passed to MyPresenter::hintsNulls() must be int, array given.'); + }, Nette\InvalidArgumentException::class, 'Argument $int passed to MyPresenter::hintsNulls() must be int, array given.'); Assert::exception(function () use ($method) { Reflection::combineArgs($method, ['int' => '1', 'bool' => '']); - }, BadRequestException::class, 'Argument $bool passed to MyPresenter::hintsNulls() must be bool, string given.'); + }, Nette\InvalidArgumentException::class, 'Argument $bool passed to MyPresenter::hintsNulls() must be bool, string given.'); Assert::exception(function () use ($method) { Reflection::combineArgs($method, ['int' => '1', 'bool' => '1', 'str' => '', 'arr' => '']); - }, BadRequestException::class, 'Argument $arr passed to MyPresenter::hintsNulls() must be array, string given.'); + }, Nette\InvalidArgumentException::class, 'Argument $arr passed to MyPresenter::hintsNulls() must be array, string given.'); }); @@ -135,23 +134,23 @@ test(function () { Assert::exception(function () use ($method) { Reflection::combineArgs($method, ['int' => '']); - }, BadRequestException::class, 'Argument $int passed to MyPresenter::hintsDefaults() must be int, string given.'); + }, Nette\InvalidArgumentException::class, 'Argument $int passed to MyPresenter::hintsDefaults() must be int, string given.'); Assert::exception(function () use ($method) { Reflection::combineArgs($method, ['int' => new stdClass]); - }, BadRequestException::class, 'Argument $int passed to MyPresenter::hintsDefaults() must be int, stdClass given.'); + }, Nette\InvalidArgumentException::class, 'Argument $int passed to MyPresenter::hintsDefaults() must be int, stdClass given.'); Assert::exception(function () use ($method) { Reflection::combineArgs($method, ['int' => []]); - }, BadRequestException::class, 'Argument $int passed to MyPresenter::hintsDefaults() must be int, array given.'); + }, Nette\InvalidArgumentException::class, 'Argument $int passed to MyPresenter::hintsDefaults() must be int, array given.'); Assert::exception(function () use ($method) { Reflection::combineArgs($method, ['int' => '1', 'bool' => '']); - }, BadRequestException::class, 'Argument $bool passed to MyPresenter::hintsDefaults() must be bool, string given.'); + }, Nette\InvalidArgumentException::class, 'Argument $bool passed to MyPresenter::hintsDefaults() must be bool, string given.'); Assert::exception(function () use ($method) { Reflection::combineArgs($method, ['int' => '1', 'bool' => '1', 'str' => '', 'arr' => '']); - }, BadRequestException::class, 'Argument $arr passed to MyPresenter::hintsDefaults() must be array, string given.'); + }, Nette\InvalidArgumentException::class, 'Argument $arr passed to MyPresenter::hintsDefaults() must be array, string given.'); }); @@ -165,23 +164,23 @@ test(function () { Assert::exception(function () use ($method) { Reflection::combineArgs($method, ['int' => '']); - }, BadRequestException::class, 'Argument $int passed to MyPresenter::defaults() must be integer, string given.'); + }, Nette\InvalidArgumentException::class, 'Argument $int passed to MyPresenter::defaults() must be integer, string given.'); Assert::exception(function () use ($method) { Reflection::combineArgs($method, ['int' => new stdClass]); - }, BadRequestException::class, 'Argument $int passed to MyPresenter::defaults() must be integer, stdClass given.'); + }, Nette\InvalidArgumentException::class, 'Argument $int passed to MyPresenter::defaults() must be integer, stdClass given.'); Assert::exception(function () use ($method) { Reflection::combineArgs($method, ['int' => []]); - }, BadRequestException::class, 'Argument $int passed to MyPresenter::defaults() must be integer, array given.'); + }, Nette\InvalidArgumentException::class, 'Argument $int passed to MyPresenter::defaults() must be integer, array given.'); Assert::exception(function () use ($method) { Reflection::combineArgs($method, ['int' => '1', 'bool' => '']); - }, BadRequestException::class, 'Argument $bool passed to MyPresenter::defaults() must be boolean, string given.'); + }, Nette\InvalidArgumentException::class, 'Argument $bool passed to MyPresenter::defaults() must be boolean, string given.'); Assert::exception(function () use ($method) { Reflection::combineArgs($method, ['int' => '1', 'bool' => '1', 'str' => '', 'arr' => '']); - }, BadRequestException::class, 'Argument $arr passed to MyPresenter::defaults() must be array, string given.'); + }, Nette\InvalidArgumentException::class, 'Argument $arr passed to MyPresenter::defaults() must be array, string given.'); }); @@ -192,17 +191,17 @@ test(function () { Assert::exception(function () use ($method) { Reflection::combineArgs($method, []); - }, BadRequestException::class, 'Missing parameter $req required by MyPresenter::objects()'); + }, Nette\InvalidArgumentException::class, 'Missing parameter $req required by MyPresenter::objects()'); Assert::exception(function () use ($method) { Reflection::combineArgs($method, ['req' => NULL, 'opt' => NULL]); - }, BadRequestException::class, 'Missing parameter $req required by MyPresenter::objects()'); + }, Nette\InvalidArgumentException::class, 'Missing parameter $req required by MyPresenter::objects()'); Assert::exception(function () use ($method) { Reflection::combineArgs($method, ['req' => $method, 'opt' => NULL]); - }, BadRequestException::class, 'Argument $req passed to MyPresenter::objects() must be stdClass, ReflectionMethod given.'); + }, Nette\InvalidArgumentException::class, 'Argument $req passed to MyPresenter::objects() must be stdClass, ReflectionMethod given.'); Assert::exception(function () use ($method) { Reflection::combineArgs($method, ['req' => [], 'opt' => NULL]); - }, BadRequestException::class, 'Argument $req passed to MyPresenter::objects() must be stdClass, array given.'); + }, Nette\InvalidArgumentException::class, 'Argument $req passed to MyPresenter::objects() must be stdClass, array given.'); });