Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Exception Laravel Package

illuminate/exception

The exception handling component of Laravel, providing the Handler that catches, reports, and renders exceptions into HTTP responses. It supports custom render and report logic, HTTP exceptions, and clean error output across your application.

View on GitHub
Deep Wiki
Context7

Getting Started

This package is a subtree split of laravel/framework — you almost never install it standalone. It arrives transitively via laravel/framework and is consumed through your app's App\Exceptions\Handler, which extends Illuminate\Foundation\Exceptions\Handler (the Foundation layer builds on top of this component).

First things to look at:

  1. App\Exceptions\Handler in your app — this is your entry point. The register(), report(), and render() methods are where you hook in.
  2. Illuminate\Contracts\Debug\ExceptionHandler — the interface the framework resolves and calls.
  3. Illuminate\Exception\Handler — the concrete implementation this package provides (report, render, renderForConsole, shouldReport).
  4. Illuminate\Exception\Renderer — the internal render()/renderViaView() helper.

First use case — custom exception reporting:

namespace App\Exceptions;

use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Illuminate\Http\Request;
use Throwable;

class Handler extends ExceptionHandler
{
    protected $dontReport = [
        \App\Exceptions\BusinessRuleException::class,
    ];

    public function register(): void
    {
        $this->reportable(function (PaymentFailed $e) {
            // fire-and-forget to Sentry, Slack, etc.
        });
    }
}

That's 90% of day-to-day interaction: you configure behavior via App\Exceptions\Handler, and this package provides the machinery underneath.

Implementation Patterns

1. Mark exceptions as self-reporting (Reportable)

use Illuminate\Contracts\Debug\ShouldntReport;
use Throwable;

class DuplicateOrderException extends \RuntimeException implements ShouldntReport
{
    // Won't hit Sentry/Flare unless you report() it manually
}

Or Reportable when you want custom side effects and no default logging:

use Illuminate\Contracts\Debug\Reportable;

class AuditFailure extends \RuntimeException implements Reportable
{
    public function report(): void
    {
        logger()->channel('audit')->error($this->getMessage(), $this->context());
    }
}

2. Mark exceptions as self-rendering (Renderable)

The exception renders itself instead of hitting the default handler:

use Illuminate\Contracts\Debug\Renderable;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

class RateLimitExceeded extends \RuntimeException implements Renderable
{
    public function render(Request $request): Response
    {
        return response()->json(['error' => 'slow down'], 429);
    }
}

For JSON/API-only apps, Responsable + render() is the cleanest path — return anything that implements the Responsable contract and Laravel will call toResponse().

3. Centralized render-by-type in the Handler

When you don't want to touch the exception class:

public function register(): void
{
    $this->renderable(function (StripeApiException $e, Request $request) {
        return $request->expectsJson()
            ? response()->json(['message' => 'Payment provider error'], 502)
            : back()->withErrors('Payment provider error');
    });

    $this->reportable(function (StripeApiException $e) {
        report($e); // forward to default pipeline
    })->stop(); // don't propagate further
}

->stop() is the extension point that prevents the callback from returning false and letting the chain continue.

4. Adding context to exceptions

Recent Laravel versions add contextualized exceptions — useful for production debugging:

class OrderFailed extends \RuntimeException
{
    public function context(): array
    {
        return ['order_id' => $this->orderId];
    }
}

This surfaces in Flare/Sentry and in the context array of structured logs — a huge win over string messages.

5. Workflow: dontReport vs. ShouldntReport

Mechanism Use when
$dontReport array in Handler Legacy / app-level exceptions you can't modify
ShouldntReport interface Exception class you own
$this->reportable(...) callback returning false Conditional suppression at runtime

Prefer the interface; the array is a maintenance liability as $dontReport grows.

6. Console vs. HTTP divergence

The Handler routes to render() (HTTP) or renderForConsole() (CLI). If you have an Artisan command that throws a domain exception you want rendered nicely to a terminal, implement renderForConsole behavior in your Handler:

protected function renderForConsole($output, Throwable $e): void
{
    if ($e instanceof MissingConfigException) {
        $output->writeln("<error>{$e->getMessage()}</error>");
        return;
    }
    parent::renderForConsole($output, $e);
}

7. Integration tip: don't report() inside a renderable()

renderable() runs after report() has already been called in the default flow. If you find yourself wanting to conditionally report based on rendering decisions, split responsibilities: use reportable() with ->stop() to make the reporting decision, and renderable() purely for response shaping.

Gotchas and Tips

  • This is read-only. Don't fork or PR against illuminate/exception. Upstream fixes belong in laravel/framework. Pin laravel/framework versions if you need stability.

  • register() is not called on every request. It's called once by the bootstrap/app.php pipeline via Application::withExceptions() in modern Laravel. If your reportable() closure closes over request-scoped data, capture it carefully — container bindings may not resolve where you think.

  • $this->renderable() runs in LIFO order and short-circuits on first non-null return. If two callbacks could match the same exception (parent class and subclass), the last registered matching callback wins. Register broader handlers first, narrower last.

  • $dontFlash doesn't stop reporting. It only affects which input fields get flashed back on validation errors — a common confusion.

  • stop() doesn't prevent logging from Laravel\Framework's default reporter. It prevents additional callback execution. The exception still hits the default report() unless you implement ShouldntReport.

  • renderable() returning a Response won't be converted for JSON automatically — you get exactly what you return, including bad status codes. If you return null, the chain continues to the next matcher.

  • Debugging Renderable: If a Renderable exception still hits the default handler, verify your class is actually autoloaded when thrown (typo in use statement is a classic). Also confirm your exception isn't caught before reaching the Handler — a try/catch in middleware short-circuits everything.

  • renderForConsole() vs. render(): Artisan commands in non-HTTP contexts sometimes show blank errors because devs override only render(). Override renderForConsole() too if you care about CLI DX.

  • Extension point for cross-cutting concerns: implement Illuminate\Contracts\Debug\ExceptionHandler on a custom class and bind it via $app->singleton(...) if you need to swap out this component entirely — rarely necessary, but documented and supported.

  • Reporting in queued jobs flows through the same Handler — your reportable() callbacks apply. If you want different reporting for background work, check app()->runningInConsole() inside the callback.

  • Version skew warning: method signatures (render($request, Throwable $e), report(Throwable $e), shouldReport(Throwable $e)) have shifted across Laravel major versions. Don't copy Handler code between Laravel 9/10/11 projects without checking the source of truth in vendor/laravel/framework/src/Illuminate/Foundation/Exceptions/Handler.php.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
dbravoan/dbcms-admin-theme-dbcms
dbravoan/dbcms-theme-db-cyber
dbravoan/dbcms-blocks-basic
dbravoan/dbcms-module-content-audit
dbravoan/dbcms-module-ai-assistant
paygate-to/paygate-php
padosoft/askmydocs-connector-base
defstudio/supercharged-carbon
bernskioldmedia/laravel-matomo
bernskioldmedia/laravel-harvest
bernskiold/laravel-data-scrubber
bernskiold/laravel-currency-converter
bernskiold/laravel-campaign-monitor
bernskioldmedia/laravel-autotranslate
siberfx/telegram-bot
roy-sandip/laravel-view-extended
gregsphotography/site-builder-core
roy-sandip/laravel-view
anodyne/blade-fluentui-icons
webx-ui/module-catalog-collections