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

Grumpy Error Bundle Laravel Package

noflash/grumpy-error-bundle

noflash/grumpy-error-bundle provides styled, more approachable error pages for Symfony applications, replacing default exception screens to make debugging clearer and failures less intimidating for users.

View on GitHub
Deep Wiki
Context7

Getting Started

What it actually is (read this first): noflash/grumpy-error-bundle is a Symfony bundle, not a Laravel package. It skins Symfony's exception/error pages — the "grumpy" gimmick is a grumpy-cat-style illustration plus snarky copy layered over the standard 404/500 output. It ships as a Symfony Bundle subclass with Twig templates under Resources/views/, wired into Symfony's exception renderer. There is no ServiceProvider, no Illuminate dependency, and nothing composer require will do for a Laravel app beyond pulling in code you cannot boot.

So "getting started" for a Laravel developer is really two paths:

  1. If you just want the effect (99% of you): skip the package, take the idea. Laravel already has first-class custom error pages:

    php artisan vendor:publish --tag=laravel-errors
    

    This drops resources/views/errors/{400,401,403,404,419,429,500,503}.blade.php into your app. Replace the contents with your grumpy layout, drop the image in public/images/, and you are done in ten minutes.

  2. If you're reading it for reference/porting: open two places in the repo — the bundle class + DependencyInjection/ extension (to see how it hooks the renderer) and Resources/views/ (to lift the markup and copy). Ignore the Symfony wiring; the templates are the only portable artifact.

First use case to try: a styled 404 only. It's the lowest-risk page, it's the one real users hit, and it lets you validate the asset pipeline and view resolution before you touch 500s.

Implementation Patterns

Layout partial, included everywhere. Don't copy markup into eight Blade files. Make resources/views/errors/layout.blade.php (or errors/partials/grumpy.blade.php) and @include it. Laravel auto-resolves errors/{status}.blade.php by HTTP status code, falling back to errors::minimal — so the partial is your single source of truth.

Gate the novelty by environment. This is the pattern the Symfony bundle can't teach you because it operates at a different layer. In Laravel:

{{-- resources/views/errors/500.blade.php --}}
@if (config('app.debug'))
    {{-- let Ignition / Whoops handle it; this view shouldn't render --}}
@endif
@include('errors.partials.grumpy', ['status' => 500])

Better: add config('app.grumpy_errors', true) and check it, so you can kill the joke in one env var during an incident without a deploy of templates.

Hook specific exceptions in the handler, not just status codes, when you want "grumpy" for domain errors:

// bootstrap/app.php (Laravel 11) or App\Exceptions\Handler
->withExceptions(function (Exceptions $exceptions) {
    $exceptions->render(function (PaymentDeclinedException $e, $request) {
        return response()->view('errors.partials.grumpy', ['status' => 402], 402);
    });
})

Mirror the bundle's copy into a lang file. If you want the snark translatable, put strings in lang/en/errors.php and reference __('errors.404.title'). The original bundle hardcodes English in Twig; that's a wart worth fixing on port.

Test it with debug off. The single most common integration bug:

public function test_grumpy_404(): void
{
    $this->get('/does-not-exist')
         ->assertStatus(404)
         ->assertSee('grumpy', escape: false);
}

For 500s you must set APP_DEBUG=false in the test environment (or config(['app.debug' => false])), otherwise you'll get the debug renderer and your test asserts against the wrong output.

Asset handling. Put the image in public/ and reference with asset('images/grumpy.webp'). Do not serve it from a route, a controller, or a Blade component that could itself throw — an error page that 500s while rendering a 500 is a genuinely fun incident.

Gotchas and Tips

  • It will not install into Laravel. Composer may resolve it, but nothing registers it. Any attempt to autoload Symfony\Component\HttpKernel\Bundle\Bundle in a Laravel app is dead weight. Treat this as "design inspiration," not a dependency. Vendor the image and the copy, not the package.
  • Maintenance risk is total. 7 stars, 0 dependents, last release January 2023. Nobody is watching this repo. Never put it in a composer.json you have to audit later — the whole value is ~50 lines of markup you can own yourself.
  • Debug mode hides everything. In APP_DEBUG=true, Laravel renders the debug exception page and your errors/500.blade.php is ignored entirely. If your new page "doesn't show up," this is why. Clear config too: php artisan config:clear.
  • View cache will bite you. php artisan view:clear after every template edit in a cached environment; otherwise you'll swear the file isn't being read (because it isn't).
  • Don't leak exception data. It's tempting to interpolate $exception->getMessage() into the grumpy copy for "helpfulness." In production that's an information-disclosure bug — stack traces, SQL, file paths. Keep production templates static; use report() for the details.
  • Cover the status codes you actually emit. 419 (CSRF expiry) and 429 (throttling) are far more common in real Laravel apps than 500, and Laravel will render its default page for any status you haven't created. If you style 404 and 500 but not 419, your users will hit the ugly one first.
  • 503 needs php artisan down awareness. The errors/503.blade.php view is what down serves; if it references assets or a layout that depends on the app booting, it breaks exactly when you need it. Make 503 fully self-contained — inline CSS, no DB, no config() reads that could fail.
  • Licensing. Before you copy the illustration into a commercial product, check the repo's license and the image's provenance. Novelty assets are frequently lifted from elsewhere; the MIT license on the code does not automatically cover the cat.
  • Extension point to remember: Laravel's errors::minimal view is the fallback for any status without a dedicated template. Override that one and you've styled every unmapped error code at once — the cheapest possible version of what this bundle does.
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.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
cgv/localized-resource