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 Handler Bundle Laravel Package

silpo-tech/exception-handler-bundle

A PHP exception-handler bundle that centralizes error handling, turning thrown exceptions into consistent responses and reducing repetitive try/catch code across your application. It helps standardize logging, error output, and handler configuration in one place.

View on GitHub
Deep Wiki
Context7

Getting Started

Before anything else, note the mismatch: despite the -bundle suffix and Symfony conventions, this is a Symfony bundle, not a Laravel package. There is no service provider, no config/exception-handler.php, and no Handler::render() hook. A Laravel developer's first move is to decide whether to (a) port the logic into App\Exceptions\Handler / a custom exception renderer, or (b) skip it and use spatie/laravel-ignition + a Problem Details package. Given the zero-star, zero-dependent, zero-score profile, option (b) is the pragmatic default.

If you are in a Symfony codebase (or evaluating for one):

  1. composer require silpo-tech/exception-handler-bundle
  2. Register in config/bundles.php (Symfony Flex usually does this automatically):
    SilpoTech\ExceptionHandlerBundle\ExceptionHandlerBundle::class => ['all' => true],
    
  3. Look first at the bundle's DependencyInjection/Configuration.php (config tree) and the EventListener/ or ExceptionHandler/ directory — that is where the exception→response mapping lives. There is no docs site; the source is the documentation.
  4. First use case: throw a domain exception from a controller and confirm you get a consistent JSON error envelope (status code, message, optional error code) instead of Symfony's default HTML error page.

The package's reason for existing is almost certainly standardizing API error responses across Silpo's services — i.e. a JSON error contract — so start by reading the default response shape and mapping table before writing any custom exception classes.

Implementation Patterns

Central mapping over per-controller try/catch. The bundle's value is that controllers throw plain exceptions and a listener converts them. Resist wrapping in try/catch; instead register your exception in the mapping config and let the handler normalize it.

Custom exception hierarchy. Define App\Exception\DomainException (or similar) and have the bundle map that base class to a default status (e.g. 400), then override specific children to 404/409/422. This keeps the mapping table small and declarative.

Config-driven status codes. Typical bundle config:

# config/packages/exception_handler.yaml
exception_handler:
    map:
        App\Exception\NotFoundException: 404
        App\Exception\ValidationException: 422
    default_status: 500
    debug: '%kernel.debug%'

Treat this file as your error contract — review it in PRs the way you review routes.

Listener priority matters. Symfony's own ErrorListener also handles kernel.exception. If your custom listener runs at the wrong priority you get either an HTML page or a double-render. Check the bundle's getSubscribedEvents() / #[AsEventListener(priority: ...)] and ensure it fires before ErrorListener (default priority is -128; the bundle should be higher).

Pair with a normalizer, not string messages. If the bundle exposes a response factory or serializer hook, feed it a structured payload (code, title, detail, traceId) rather than raw $e->getMessage(). This is what makes the envelope useful to clients.

Log at the boundary, not in the handler. Let the exception handler render; let Monolog/Sentry capture via a separate listener. Mixing them makes it impossible to render a 404 for a NotFoundHttpException without a false-positive error log.

Testing. Use KernelBrowser/WebTestCase and assert on application/problem+json (or whatever content type the bundle emits) plus the status code. Add one test per mapped exception class so the contract is pinned.

Laravel port pattern, if you go that route: reimplement the mapping as a match(true) inside a custom ExceptionRenderer contract implementation, and register it alongside Laravel's default HttpException renderer. You lose the bundle's listeners and get none of its maintenance — which, at zero dependents, you weren't getting anyway.

Gotchas and Tips

  • Debug mode divergence. In %kernel.debug%, Symfony typically re-throws or renders a trace page. Verify the bundle respects debug and does not leak stack traces or SQL in production responses. Audit this explicitly — it's the most common bug class in exception bundles.
  • The release date is suspicious. 2026-10-23 is in the future relative to any reasonable "now." That suggests either a metadata/feed error, an unpushed tag, or a package that is effectively unmaintained and mis-tagged. Do not assume semantic-versioning stability; pin an exact version and inspect the tag.
  • Zero adoption means zero safety net. No dependents, no stars, no Stack Overflow answers. You are the first integration tester. Budget for reading the source end-to-end before depending on it in production, and consider vendoring or forking.
  • Namespace/bundle naming. The silpo-tech org makes this a de-facto internal bundle published publicly. Internal bundles frequently hardcode assumptions (logging channels, APP_ENV names, response shapes) that won't match yours.
  • Do not rely on getMessage() for client output. It leaks internals and is not stable across locales. Map exception types to client-facing strings.
  • kernel.exception recursion. If your handler itself throws (e.g. the serializer fails), Symfony falls back to a bare 500. Guard the handler with a try/catch that logs and returns a minimal envelope.
  • Extension point to watch for: a response_factory or normalizer service alias in the DI config. If present, override it in services.yaml — that's the cleanest customization seam. If absent, you'll be decorating the listener, which is fragile.
  • License is MIT (per metadata) — fine for forking. If you port it to Laravel, keep the copyright header and note the origin; it costs nothing and keeps the audit trail clean.
  • Final recommendation for a Laravel team: read it as reference material for how to structure an error contract, not as a dependency. The concepts (central mapping, Problem Details envelope, listener priority) transfer; the code does not.
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.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource