Exceptions
Every exception lives in RoundlyConsulting\Attributes\Exceptions and extends AttributesException, so one catch covers them all:
| Exception | Thrown when | Carries |
|---|---|---|
UnknownAttributeException | Strict mode is on and a value or meta write names an attribute with neither a global nor a model-schema definition. | — |
InvalidAttributeValueException | A value fails its definition’s type or rules, or cannot be encoded to its type. | attributeName, messages(), errorBag() |
DuplicateAttributeValueException | A unique definition’s value is already held by another owner — caught before the write, or by the unique index when two writers race. | attributeName, scope |
MissingRequiredAttributeException | validateAttributes() finds a required attribute absent. | attributeName |
AttributesException | Base class of all four (extends RuntimeException). | — |
Misconfiguration — an invalid config value or definition — throws the toolkit’s RoundlyConsulting\PackageToolkit\Exceptions\InvalidConfigurationException instead, which is not an AttributesException. Its message names the offending key.
Friendly validation errors
InvalidAttributeValueException carries the failing attribute name and the full validator bag. messages() prefixes each message with the attribute name:
use RoundlyConsulting\Attributes\Exceptions\AttributesException;
use RoundlyConsulting\Attributes\Facades\Attributes;
use RoundlyConsulting\Attributes\Exceptions\InvalidAttributeValueException;
try {
Attributes::for($product)->set('rating', 9);
} catch (InvalidAttributeValueException $e) {
$e->attributeName; // 'rating'
$e->messages(); // ['rating: The rating field must not be greater than 5.']
$e->errorBag(); // Illuminate\Support\MessageBag|null
} catch (AttributesException $e) {
report($e); // unknown, duplicate or missing-required attribute
}When a value cannot be encoded to its type at all, the exception has no validator bag — errorBag() returns null and messages() an empty list; getMessage() explains the reason.
Returning a validation response
Rethrow as Laravel’s ValidationException to get the usual 422 response or redirect with errors:
use Illuminate\Validation\ValidationException;
use RoundlyConsulting\Attributes\Exceptions\InvalidAttributeValueException;
use RoundlyConsulting\Attributes\Facades\Attributes;
try {
Attributes::for($product)->stage()
->set('rating', $request->integer('rating'))
->save();
} catch (InvalidAttributeValueException $e) {
throw ValidationException::withMessages([
(string) $e->attributeName => $e->errorBag()?->all() ?? [$e->getMessage()],
]);
}Show your open-source love
This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.
More ways to support, including cryptoBy donating, you agree to our donation terms.
Want this built into your product?
We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.