NewWe open-sourced 50+ Laravel packages
Custom AI apps, agents and automation — Roundly ConsultingRoundly
All packages

Every client-facing exception extends the abstract Exceptions\EventsException (a RuntimeException). errorCode() is the stable code, status() the HTTP status the API answers with, and getMessage() is already the client-safe text — translated into the current locale (events::messages, en and sk), never naming a class, key or table. In your own controllers:

use RoundlyConsulting\Events\Exceptions\EventsException;

try {
    $rsvp = Events::for($event)->rsvp($request->user())->by($request->user())->going(tier: $request->input('tier'));
} catch (EventsException $e) {
    return response()->json(['message' => $e->getMessage(), 'code' => $e->errorCode()], $e->status());
}
ExceptioncodeHTTPThrown when
EventNotFoundExceptionevent_not_found404An unknown, trashed or (over the API) hidden event; a calendar file for a viewer who may not see the event.
VenueNotFoundException · TierNotFoundExceptionvenue_not_found · tier_not_found404A ticket type of another event, or an unknown key or id.
RsvpNotFoundExceptionrsvp_not_found404An RSVP of another event; an unknown or superseded payment reference; a check-in for an attendee whose row is gone.
InvalidEventExceptioninvalid_event422Title missing or too long, a bad join link, a mode that disagrees with venue and link, a new start on an announced event, deleting an event people are going to, bad reminders, no organizer, a taken manual slug, moving a finished event online, an invitation message over 1000.
InvalidEventScheduleExceptioninvalid_schedule422No start, end before start, too long, doors outside the 12 hours before the start, a bad timezone, date-time or duration, a time in a DST gap, a bad all-day range or RSVP window.
InvalidVenueExceptioninvalid_venue / venue_in_use422No name, bad coordinates, a bad country code, a radius out of range / deleting a venue an unfinished event uses.
InvalidTierExceptioninvalid_tier / tier_key_taken / tier_in_use422Bad name, key, party limits, sale window, capacity, price or reorder / a taken key / removing a ticket type in use.
InvalidGuestCountException · TierRequiredExceptioninvalid_guest_count · tier_required422Guests outside the limits · going() without a ticket type while several are on sale.
TierNotOnSaleException · EventFullException · TierSoldOutExceptiontier_not_on_sale · event_full · tier_sold_out409A newly picked type outside its sale · no seats and no waitlist.
RsvpClosedExceptionrsvp_closed409RSVPs closed or not open yet, the event started, cancelled or completed — and a payment from the start on (refund it).
InvitationRequiredExceptioninvitation_required403Answering a private event without an invitation.
InvalidRsvpTransitionExceptioninvalid_rsvp_transition409A checked-in attendee declining or shrinking below the guests through the door, a paid seat changed by answering, confirming or releasing what is not held, checking in what is not going.
RsvpHoldExpiredExceptionhold_expired409A late payment with no seats left.
InvalidCheckInCodeException · CheckInRefusedExceptioninvalid_code · check_in_refused404 · 409See Check-in at the door.
InvalidInvitationExceptioninvalid_invitation404An unknown, malformed, revoked, expired or used token, or someone else’s link — uniform.
EventTrashedExceptionevent_trashed409Any write to a trashed event.
UnknownEventTransitionException · EventTransitionDeniedExceptionunknown_transition · transition_denied422 (429)A verb the lifecycle does not offer · lifecycle refused (denials(), retryAfterSeconds(), previousDenial()).
InvalidOrganizerException · UnknownMorphAliasException · InvalidEventQueryExceptioninvalid_organizer · unknown_alias · invalid_query422 (400)Organizing as someone who does not allow the actor · an unknown API alias or key · a bad API filter value.

EventTransitionDeniedException also has denials() (lifecycle’s denial codes plus no_attendees and rescheduled_through_events), retryAfterSeconds() (0 unless rate limited; the API sends Retry-After) and previousDenial(). CheckInRefusedException::reason() is one of the constants WRONG_EVENT, NOT_GOING, EVENT_NOT_ACTIVE and OUTSIDE_WINDOW.

Errors the API maps from elsewhere

SourceAPI answer
Laravel’s AuthorizationException403 forbidden
lifecycle’s SubjectTrashedException409 event_trashed
tags’ TagNotFoundException, TagScopeMismatchException422 tag_not_found
tags’ TagLimitExceededException422 tag_limit_exceeded
tags’ InvalidTagException, TagTypeMismatchException, TagTypeNotAllowedException, UnknownTagTypeException422 invalid_tag
media-library’s FileUnacceptableForBucket, DraftMediaNotFound, DraftMediaExpired422 invalid_poster
Validation422 validation_failed + errors

In PHP these pass through unchanged.

Configuration errors

These are the host’s to fix: English, naming the key, and extending the toolkit’s PackageToolkitException. InvalidEventsConfigurationException covers a bad duration, timezone, table name, time of day, URL template or choice — outOfRange() for a value outside its bounds, tooMany() for more than five reminder offsets and keyTypeMismatch() when a model’s key does not fit events.key_type, raised before any SQL. InvalidEventLifecycleException covers an events.lifecycle value that is not a LifecycleDefinition implementing Contracts\EventLifecycle, or one that breaks the contract. The toolkit’s own InvalidConfigurationException covers a model, resource, notification class or list that is not what its key needs.

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 crypto

By 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.