# Laravel Exceptions

> Custom exceptions with static factories and HTTP responses. Use when creating or modifying exceptions or error handling.

- Skill: `leeovery/laravel-exceptions` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add leeovery/laravel-exceptions`
- Raw SKILL.md: https://api.skillmd.com/api/skills/leeovery/laravel-exceptions/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: leeovery (https://skillmd.com/u/leeovery)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/leeovery/laravel-exceptions

---


# Laravel Exceptions

Custom exceptions use **static factory methods** and implement `HttpExceptionInterface`.

**Related guides:**
- [Actions](../laravel-actions/SKILL.md) - Throwing exceptions in actions

## Structure

```php
<?php

declare(strict_types=1);

namespace App\Exceptions;

use App\Exceptions\Concerns\Httpable;
use App\Models\Order;
use Exception;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;

class OrderException extends Exception implements HttpExceptionInterface
{
    use Httpable;

    public static function notFound(string|int $orderId): self
    {
        return new self("Order {$orderId} not found.", 404);
    }

    public static function cannotCancelOrder(Order $order): self
    {
        return new self(
            "Order {$order->uuid} cannot be cancelled in its current state.",
            400
        );
    }

    public static function insufficientStock(string $productName): self
    {
        return new self(
            "Insufficient stock for product: {$productName}",
            422
        );
    }

    public static function paymentFailed(string $reason): self
    {
        return new self("Payment failed: {$reason}", 402);
    }
}
```

## Httpable Concern

**[View full implementation →](references/Httpable.php)**

## Usage

### Throwing Exceptions

```php
// In actions
throw OrderException::notFound($orderId);
throw OrderException::cannotCancelOrder($order);
throw OrderException::insufficientStock($product->name);
```

### With throw_unless/throw_if

```php
class CancelOrderAction
{
    public function __invoke(Order $order): Order
    {
        throw_unless(
            $order->canBeCancelled(),
            OrderException::cannotCancelOrder($order)
        );

        // Continue with cancellation
    }
}
```

### Guard Methods

```php
class ProcessOrderAction
{
    public function __invoke(Order $order): void
    {
        $this->guard($order);

        // Process order
    }

    private function guard(Order $order): void
    {
        throw_unless(
            $order->isPending(),
            OrderException::cannotProcessOrder($order)
        );

        throw_unless(
            $order->hasItems(),
            OrderException::orderHasNoItems($order)
        );
    }
}
```

## Key Patterns

### 1. Static Factory Methods

Named constructors for specific exceptions:

```php
public static function notFound(string|int $orderId): self
{
    return new self("Order {$orderId} not found.", 404);
}
```

### 2. HTTP Status Codes

Pass status as second constructor parameter:

```php
new self("Message", 404);  // Not Found
new self("Message", 400);  // Bad Request
new self("Message", 422);  // Unprocessable Entity
new self("Message", 403);  // Forbidden
```

### 3. Descriptive Messages

Include context in error messages:

```php
"Order {$order->uuid} cannot be cancelled"
"Insufficient stock for product: {$productName}"
```

### 4. HttpExceptionInterface

Implement interface for automatic HTTP error responses:

```php
class OrderException extends Exception implements HttpExceptionInterface
{
    use Httpable;
}
```

## Common HTTP Status Codes

- `400` - Bad Request (business rule violation)
- `402` - Payment Required
- `403` - Forbidden (authorization failed)
- `404` - Not Found
- `422` - Unprocessable Entity (validation failed)
- `500` - Internal Server Error

## Directory Structure

```
app/Exceptions/
├── OrderException.php
├── PaymentException.php
├── UserException.php
└── Concerns/
    └── Httpable.php
```

## Summary

**Exceptions should:**
- Use static factory methods
- Implement `HttpExceptionInterface`
- Include HTTP status codes
- Have descriptive messages with context
- Be named `{Entity}Exception`

**Use for business rule violations and error conditions.**

