Intercept throwables in the "Call" rule

The callable defined to the "Call" rule may also throw an exception and
as we don't want to have errors nor exceptions that are not part of the
Validation during the validation of inputs it just makes sense to
intercept any instance of Throwable.

This change was initially thought of because in Travis the version 7.4
of PHP was throwing "Error" instead of triggering PHP errors which made
the tests fail.

Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
This commit is contained in:
Henrique Moody 2018-08-21 10:39:43 +02:00
parent 2fac861aa1
commit d64d26c681
No known key found for this signature in database
GPG key ID: 221E9281655813A6
2 changed files with 58 additions and 2 deletions

View file

@ -15,6 +15,7 @@ namespace Respect\Validation\Rules;
use Respect\Validation\Exceptions\ValidationException;
use Respect\Validation\Validatable;
use Throwable;
use function call_user_func;
use function restore_error_handler;
use function set_error_handler;
@ -57,7 +58,13 @@ final class Call extends AbstractRule
{
$this->setErrorHandler($input);
$this->rule->assert(call_user_func($this->callable, $input));
try {
$this->rule->assert(call_user_func($this->callable, $input));
} catch (ValidationException $exception) {
throw $exception;
} catch (Throwable $throwable) {
throw $this->reportError($input);
}
restore_error_handler();
}
@ -69,7 +76,13 @@ final class Call extends AbstractRule
{
$this->setErrorHandler($input);
$this->rule->check(call_user_func($this->callable, $input));
try {
$this->rule->check(call_user_func($this->callable, $input));
} catch (ValidationException $exception) {
throw $exception;
} catch (Throwable $throwable) {
throw $this->reportError($input);
}
restore_error_handler();
}

View file

@ -13,6 +13,7 @@ declare(strict_types=1);
namespace Respect\Validation\Rules;
use Exception;
use PHPUnit\Framework\TestCase;
use Respect\Validation\Exceptions\AlwaysInvalidException;
use Respect\Validation\Exceptions\CallException;
@ -67,6 +68,27 @@ final class CallTest extends TestCase
$sut->assert($input);
}
/**
* @test
*/
public function assertShouldThrowCallExceptionWhenCallableThrowsAnException(): void
{
$input = [];
$callable = function (): void {
throw new Exception();
};
$rule = $this->createMock(Validatable::class);
$rule
->expects(self::never())
->method('assert');
$this->expectException(CallException::class);
$sut = new Call($callable, $rule);
$sut->assert($input);
}
/**
* @test
*/
@ -120,6 +142,27 @@ final class CallTest extends TestCase
$sut->assert($input);
}
/**
* @test
*/
public function checkShouldThrowCallExceptionWhenCallableThrowsAnException(): void
{
$input = [];
$callable = function (): void {
throw new Exception();
};
$rule = $this->createMock(Validatable::class);
$rule
->expects(self::never())
->method('check');
$this->expectException(CallException::class);
$sut = new Call($callable, $rule);
$sut->assert($input);
}
/**
* @test
*/