Exceptions
Every exception the package throws for a call it refuses extends TagsException (a RuntimeException). Present them through four stable methods rather than knowing each class: errorCode() — a snake_case code, public API from 1.0; status() — the HTTP status for a reference in a request body; isNotFound() — the not-found family, which answers 404 when the reference was a path segment; clientMessage() — the translated text a client may see. Messages come from tags::messages in English and Slovak and never name a PHP class:
use RoundlyConsulting\Tags\Exceptions\TagsException;
try {
$concert->attachTags($request->input('labels', []), 'label');
} catch (TagsException $e) {
return response()->json(
['message' => $e->clientMessage(), 'code' => $e->errorCode()],
$e->status(),
);
}| Exception | errorCode() | status() | When |
|---|---|---|---|
UnknownTagTypeException | unknown_tag_type / type_required | 404 / 422 | A type nobody defined (or one hidden from the caller); a string input with no type while there is no default type. |
TagNotFoundException | tag_not_found | 422 (404 in the path) | A key, slug or name that matches no live tag the caller may use; a deleted tag. |
TagScopeMismatchException | tag_not_found | 422 (404 in the path) | A tag of another scope — presents exactly like a missing one; getMessage() keeps the precise text for logs. |
DuplicateTagException | duplicate_tag | 409 | A name or manual slug whose slug another tag of the type and scope holds — names the slug and the locale, and points to restore() when a deleted tag holds it. |
InvalidTagException | invalid_tag | 422 | A blank, too long or unsluggable name, an unsupported or malformed locale, a bad colour, icon, description, slug or position, a manual slug on a free-form type, a scope on a global-only type, a change to type or owner. |
InvalidTagHierarchyException | invalid_hierarchy | 422 | A cycle, a tree deeper than the type allows, a parent on a flat type, a deleted parent. |
TagHasChildrenException | tag_has_children | 409 | A delete that would orphan live children — pass TagChildren::Reparent or Delete. |
TagLimitExceededException | tag_limit_exceeded | 422 | A write that would leave a model with more tags of a type than allowed; nothing is written. |
TagTypeMismatchException | tag_type_mismatch | 422 | A tag of one type used where another was asked for — a tagging call, a parent, a handle. |
TagTypeNotAllowedException | tag_type_not_allowed | 422 | The type’s on() list or the model’s tagTypes() leaves the other out. |
UnknownMorphAliasException | unknown_alias | 422 | An API scope or taggable reference the allow-lists do not hold — or a scope the caller may not use, which answers the same. |
InvalidTagTypeException | invalid_tag_type | 500 | A type definition that cannot work (see Tag types). |
TagTypeAlreadyDefinedException | type_already_defined | 500 | A second definition of one name, naming both definers. |
UnsavedTaggableException | unsaved_taggable | 500 | Tagging a model that is not saved yet. |
- A missing key presents to clients exactly like a tag of another scope: clientMessage() is the generic “The tag does not exist.” while getMessage() keeps the key for your logs.
- Outside the family: InvalidTagsConfigurationException (configuration the package cannot work with, named by its key — it extends the toolkit’s exception, so catch it beside InvalidConfigurationException) and ReadOnlyTagsRelationException (a LogicException for a write through tags()).
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.