2025-12-07
#backend
#error-handling
#laravel
Enterprise Exception Handling
Centralized error handling using Marker Interfaces and global handlers.
The project uses a centralized approach to error handling based on Marker Interfaces. This keeps the domain layer clean of HTTP dependencies.
Principles
- Clean Domain: Domain exceptions (
ReservationExpiredException) know nothing about HTTP statuses (404, 422). They simply state a business logic error fact. - Happy Path Controllers: Controllers do not use
try-catch. They expect successful execution. - Global Handler: A single component in the
Corelayer converts exception types into HTTP responses.
Implementation
1. Marker Interfaces (Core Layer)
Interfaces corresponding to error types are defined in app/Core/Exceptions:
phpinterface UnauthorizedExceptionInterface {} // -> 401 interface ConflictExceptionInterface {} // -> 409 interface UnprocessableExceptionInterface {} // -> 422
2. Domain Exceptions (Domain Layer)
Exceptions implement the corresponding interfaces:
phpclass DoubleBookingException extends Exception implements ConflictExceptionInterface { protected $message = "This slot is already booked."; }
3. Handling (Core Layer)
CustomExceptionHandler intercepts exceptions and uses a response factory:
php// In the register(Exceptions $exceptions) method $exceptions->render(function (Throwable $e) { if ($e instanceof ConflictExceptionInterface) { // Forms a standardized JSON response return $this->responseFactory->conflict($e->getMessage()); } return null; });
Advantages
- DRY: No need to write
try-catchin every controller. - Consistency: API error format (JSON structure) is guaranteed to be uniform across the application.
- Clarity: The exception class immediately indicates the category of error it belongs to.