refactor(request): propagate validation failures as exceptions
This commit is contained in:
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
namespace Libs;
|
namespace Libs;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Request - DuckBrain
|
* Request - DuckBrain
|
||||||
*
|
*
|
||||||
@@ -59,17 +61,20 @@ class Request extends Neuron
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Run configured validations
|
// Run configured validations
|
||||||
if (!$this->validate()) {
|
$this->validate();
|
||||||
exit();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Starts the configured validation.
|
* Starts the configured validation.
|
||||||
*
|
*
|
||||||
* @return bool
|
* On failure the single error message is built with Validator::message()
|
||||||
|
* and handed to onInvalid(), which throws by default: failures travel up
|
||||||
|
* as exceptions instead of answering HTTP here.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
* @throws Exception When a configured rule fails.
|
||||||
*/
|
*/
|
||||||
public function validate(): bool
|
public function validate(): void
|
||||||
{
|
{
|
||||||
$actual = match ($_SERVER['REQUEST_METHOD']) {
|
$actual = match ($_SERVER['REQUEST_METHOD']) {
|
||||||
'POST', 'PUT', 'PATCH', 'DELETE' => $this->{strtolower($_SERVER['REQUEST_METHOD'])},
|
'POST', 'PUT', 'PATCH', 'DELETE' => $this->{strtolower($_SERVER['REQUEST_METHOD'])},
|
||||||
@@ -88,7 +93,7 @@ class Request extends Neuron
|
|||||||
Validator::validateList(static::getRules(), $this->get) &&
|
Validator::validateList(static::getRules(), $this->get) &&
|
||||||
Validator::validateList(static::rules(), $body)
|
Validator::validateList(static::rules(), $body)
|
||||||
) {
|
) {
|
||||||
return true;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$error = Validator::message(
|
$error = Validator::message(
|
||||||
@@ -98,7 +103,6 @@ class Request extends Neuron
|
|||||||
);
|
);
|
||||||
|
|
||||||
static::onInvalid($error);
|
static::onInvalid($error);
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -157,27 +161,20 @@ class Request extends Neuron
|
|||||||
/**
|
/**
|
||||||
* Function to execute when an invalid value has been detected.
|
* Function to execute when an invalid value has been detected.
|
||||||
*
|
*
|
||||||
* Always answers with a single error and HTTP 422. The representation is
|
* The default implementation always throws a generic \Exception carrying
|
||||||
* negotiated from the request's Accept header: JSON when the client asks
|
* the single error message and HTTP 422 as its code; the framework's
|
||||||
* for application/json, plain text otherwise.
|
* exception boundary (Router::apply) renders the response. Override it to
|
||||||
|
* throw a more specific exception type instead. The never return type is
|
||||||
|
* the contract: an override that returned would let the request continue
|
||||||
|
* with invalid data, so PHP rejects such an override at compile time.
|
||||||
*
|
*
|
||||||
* @param string $error
|
* @param string $error
|
||||||
*
|
*
|
||||||
* @return void
|
* @return never
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function onInvalid(string $error): void
|
public function onInvalid(string $error): never
|
||||||
{
|
{
|
||||||
http_response_code(422);
|
throw new Exception($error, 422);
|
||||||
|
|
||||||
$accept = $_SERVER['HTTP_ACCEPT'] ?? '';
|
|
||||||
|
|
||||||
if (str_contains($accept, 'application/json')) {
|
|
||||||
header('Content-Type: application/json');
|
|
||||||
print(json_encode(['error' => $error]));
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
print($error);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user