Error Collector
Grape relies on an error collector to manage validation errors and build the messages array returned with the ValidationException. This collector is responsible for formatting the errors you receive after a validation call.
Grape includes a default SimpleErrorCollector, which is used by default. However, you can implement your own collector to suit your specific needs.
The SimpleErrorCollector
The SimpleErrorCollector is automatically registered as Grape's default error collector. It provides a straightforward implementation for collecting and formatting validation errors. The error collector returns an associative array of messages, where the keys are field names and the values are arrays of error messages. Each error message contains three keys:
message: The validation error message.rule: The name of the validation rule that failed.path: The field's path in the data structure.
Example of the Error Array
Here is an example of what the error array might look like:
[
'username' => [
[
'message' => 'The username is required.',
'rule' => 'required',
'path' => 'username',
],
],
'email' => [
[
'message' => 'The email must be a valid email address.',
'rule' => 'email',
'path' => 'email',
],
],
]Customizing the ValidationException Message
The default message for ValidationException is "Validation failed." You can customize this message by setting up a custom instance of SimpleErrorCollector:
use Potager\Grape\Collectors\SimpleErrorCollector;
use Potager\Grape\Grape;
$errorCollectorFactory = fn () => new SimpleErrorCollector("Your custom exception message");
Grape::setErrorCollector($errorCollectorFactory);Creating a Custom Error Collector
An error collector is a class that must implement the ErrorCollectorContract. This interface defines the methods Grape uses to collect and format validation errors.
The
hasError()method checks if any errors have been collected and must return a boolean value.The
report()method is called by Grape whenever a validation error occurs. This method receives the following parameters:- The current
FieldContext - The name of the rule that failed
- The validation error message
- The current
The
createError()method is used to generate an instance ofValidationExceptioncontaining the collected error messages. This exception is thrown when validation fails.
use Potager\Grape\Contracts\ErrorCollectorContract;
class CustomErrorCollector implements ErrorCollectorContract
{
private array $errors = [];
public function hasError(): bool
{
return !empty($this->errors);
}
public function report(FieldContext $context, string $rule, string $message): void
{
// Define how to store the reported errors
$this->errors[] = [
'field' => $context->getField(),
'rule' => $rule,
'message' => $message,
'messageAndRule' => $message . ' (' . $rule . ')',
];
}
public function createError(): ValidationException
{
return new ValidationException($this->errors, "Custom validation error");
}
}Registering an Error Collector
You can register an error collector globally, for a specific validator, or for a single validation call.
Since a fresh instance of the collector is required for each validation, you need to provide a factory that returns a new instance of your error collector.
Register Globally
$errorCollectorFactory = fn () => new CustomErrorCollector();
Grape::setErrorCollector($errorCollectorFactory);Register for a Validator
$errorCollectorFactory = fn () => new CustomErrorCollector();
$validator = Grape::string();
$validator->setErrorCollector($errorCollectorFactory);Register for a Single Validation Call
$collector = new CustomErrorCollector();
$validator = Grape::string();
$validator->validate($payload, errorCollector: $collector);