adaptit-darshan/exception-notifier

Production-ready exception notification system for Laravel 12+ with intelligent rate limiting, critical exception handling, and customizable email templates. Major v2.0 upgrade with modern Laravel 12 support.

Installs: 1 175

Dependents: 0

Suggesters: 0

Security: 0

Stars: 6

Watchers: 4

Forks: 0

Open Issues: 0

pkg:composer/adaptit-darshan/exception-notifier

v1.2.0 2025-11-19 02:45 UTC

This package is auto-updated.

Last update: 2025-11-19 02:50:27 UTC


README

Latest Version on Packagist Total Downloads License

Version 2.0 - Major upgrade with Laravel 12+ support! ๐Ÿš€

Laravel Exception Notifier is a production-ready exception notification system for Laravel 12+ applications. Get instant email alerts when exceptions occur in your application with intelligent rate limiting, customizable templates, and comprehensive context data.

๐Ÿ†• What's New in v2.0

  • โœจ Laravel 12+ Support - Modern bootstrap/app.php pattern
  • โœจ PHP 8.2+ Required - Latest PHP features and performance
  • โœจ Per-Signature Rate Limiting - Each exception tracked separately
  • โœจ Critical Exception Bypass - Important errors always notify
  • โœจ Enhanced Bot Detection - Better false positive filtering
  • โœจ Zero-Loop Guarantee - Fixed infinite loop bug with dependency injection
  • โœจ Email Branding - Customizable logo, colors, and footer

Upgrading from v1.x? See UPGRADE.md for migration guide.

โœจ Features

  • ๐Ÿšจ Instant Email Notifications - Get notified immediately when exceptions occur
  • ๐ŸŽฏ Smart Rate Limiting - Per-exception-signature rate limiting to prevent email spam
  • ๐Ÿ”ฅ Critical Exception Bypass - Critical exceptions always bypass rate limits
  • ๐Ÿ“Š Rich Context Data - Stack traces, request details, user information, and more
  • ๐ŸŽจ Customizable Email Templates - Beautiful, responsive HTML email templates
  • ๐Ÿค– Bot Detection - Automatically ignore exceptions from bots and crawlers
  • ๐Ÿ”ง Artisan Commands - Manage rate limits and test notifications via CLI
  • ๐ŸŒ Environment-Aware - Silent mode in local environment during development
  • ๐Ÿ“ Detailed Logging - All exceptions still logged even when email suppressed
  • โšก Zero Performance Impact - Notifications wrapped in try-catch to never break your app

๐Ÿ“‹ Requirements

  • PHP 8.2 or higher
  • Laravel 12.0 or higher
  • Mail configuration (SMTP, Mailgun, SES, etc.)

๐Ÿ“ฆ Installation

Install the package via Composer:

composer require damku999/exception-notifier

Publish Configuration

Publish the configuration file:

php artisan vendor:publish --tag="exception-notifier-config"

This will create config/exception_notifier.php with all available options.

Publish Email Templates (Optional)

If you want to customize the email templates:

php artisan vendor:publish --tag="exception-notifier-views"

Templates will be published to resources/views/vendor/exception-notifier/.

Publish Migrations (Optional)

If you want to use database-backed rate limiting:

php artisan vendor:publish --tag="exception-notifier-migrations"
php artisan migrate

โš™๏ธ Configuration

Environment Variables

Add these to your .env file:

# Enable exception email notifications (default: false)
EXCEPTION_EMAIL_ENABLED=true

# Silent mode in local environment (default: true)
EXCEPTION_EMAIL_SILENT_LOCAL=true

# Email recipients (comma-separated)
EXCEPTION_EMAIL_TO=admin@example.com,dev@example.com

# Rate limiting (default: 10 emails per hour per signature)
EXCEPTION_EMAIL_MAX_PER_HOUR=10
EXCEPTION_EMAIL_RATE_WINDOW=3600

Basic Setup

Update your bootstrap/app.php to use the exception notifier:

<?php

use Damku999\ExceptionNotifier\JsonExceptionHandler;
use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Foundation\Configuration\Middleware;

return Application::configure(basePath: dirname(__DIR__))
    ->withRouting(
        web: __DIR__.'/../routes/web.php',
        api: __DIR__.'/../routes/api.php',
        commands: __DIR__.'/../routes/console.php',
        health: '/up',
    )
    ->withMiddleware(function (Middleware $middleware) {
        //
    })
    ->withExceptions(function (Exceptions $exceptions) {
        $exceptions->render(function (Throwable $e) {
            return app(JsonExceptionHandler::class)->handle($e);
        });
    })->create();

Advanced Configuration

Edit config/exception_notifier.php for advanced options:

return [
    // Enable/disable globally
    'enabled' => env('EXCEPTION_EMAIL_ENABLED', false),

    // Silent mode in local environment
    'silent_in_local' => env('EXCEPTION_EMAIL_SILENT_LOCAL', true),

    // Email recipients
    'recipients' => array_filter(array_map('trim', explode(',', env('EXCEPTION_EMAIL_TO', '')))),

    // Fallback recipients if none specified
    'fallback_recipients' => ['admin@example.com'],

    // Rate limiting
    'max_emails_per_signature_per_hour' => env('EXCEPTION_EMAIL_MAX_PER_HOUR', 10),
    'rate_limit_window' => env('EXCEPTION_EMAIL_RATE_WINDOW', 3600),

    // Ignored exceptions (won't send emails)
    'ignored_exceptions' => [
        \Illuminate\Validation\ValidationException::class,
        \Symfony\Component\HttpKernel\Exception\NotFoundHttpException::class,
        \Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException::class,
        \Illuminate\Auth\AuthenticationException::class,
    ],

    // Critical exceptions (bypass rate limits)
    'critical_exceptions' => [
        \Illuminate\Database\QueryException::class,
    ],

    // Bot user agents to ignore
    'ignored_bots' => [
        'googlebot', 'bingbot', 'crawler', 'spider', 'bot',
    ],

    // Include context data in emails
    'include_request_data' => true,
    'include_user_data' => true,
    'include_stack_trace' => true,
    'max_stack_trace_depth' => 10,

    // Send suppression notice when rate limit reached
    'send_suppression_notice' => true,
];

๐Ÿš€ Usage

Automatic Exception Handling

Once configured in bootstrap/app.php, the package automatically catches and notifies you of exceptions:

// Any uncaught exception will trigger an email notification
throw new \Exception('Something went wrong!');

// Validation exceptions are ignored by default (configurable)
throw ValidationException::withMessages(['email' => 'Invalid email']);

// Database exceptions are marked as critical (always sent)
DB::table('non_existent')->get(); // Triggers critical email

Manual Exception Notification

You can manually trigger exception notifications:

use Damku999\ExceptionNotifier\Facades\ExceptionNotifier;

try {
    // Your code
} catch (\Throwable $e) {
    ExceptionNotifier::notify($e);

    // Continue with your error handling
}

Checking Rate Limits

use Damku999\ExceptionNotifier\Facades\ExceptionNotifier;

// Check if rate limit exceeded for specific exception
$signature = ExceptionNotifier::generateSignature($exception);
$exceeded = ExceptionNotifier::isRateLimitExceeded($signature);

// Get current count for signature
$count = ExceptionNotifier::getRateLimitCount($signature);

// Get all rate limit statuses
$statuses = ExceptionNotifier::getRateLimitStatus();

๐Ÿ”ง Artisan Commands

View Rate Limit Status

View current rate limit status for all exception signatures:

php artisan exception:rate-limit-status

Output:

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Exception Signature                                          โ”‚ Count โ”‚ Max โ”‚ TTL (s)  โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ Exception:app/Http/Controllers/UserController.php:45         โ”‚ 8     โ”‚ 10  โ”‚ 2847     โ”‚
โ”‚ QueryException:app/Models/User.php:123                       โ”‚ 15    โ”‚ 10  โ”‚ 1523     โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Clear Rate Limits

Clear all rate limits:

php artisan exception:clear-rate-limits

Clear specific signature:

php artisan exception:clear-rate-limits --signature="Exception:app/Http/Controllers/UserController.php:45"

Test Exception Emails

Send a test exception email:

php artisan exception:test

Send test with custom exception type:

php artisan exception:test --type=critical

๐Ÿ“ง Email Templates

The package includes two beautiful, responsive email templates:

Exception Notification Email

Sent when an exception occurs (within rate limits):

  • Exception Summary - Class, message, file, line, signature
  • Stack Trace - Formatted call stack with file/line numbers
  • Request Details - URL, method, IP, user agent
  • User Context - Authenticated user information
  • Environment Info - Environment name and timestamp
  • Rate Limit Status - Current count vs maximum allowed

Rate Limit Suppression Email

Sent once when rate limit is reached:

  • Rate Limit Info - Signature, max count, time remaining
  • What This Means - Explanation of suppression
  • Action Required - Steps to investigate and resolve
  • Helpful Commands - CLI commands to manage rate limits

Customizing Templates

Publish the views and edit them:

php artisan vendor:publish --tag="exception-notifier-views"

Templates location: resources/views/vendor/exception-notifier/

Customizing Email Branding

Override the branding configuration:

// In your AppServiceProvider or config
config([
    'exception_notifier.branding' => [
        'email_logo' => 'images/logo.png',
        'primary_color' => '#007bff',
        'text_color' => '#333333',
        'footer_text' => 'Your Company Name',
        'support_email' => 'support@example.com',
    ],
]);

๐Ÿงช Testing

Run the test suite:

composer test

Run tests with coverage:

composer test:coverage

๐Ÿ“Š Exception Signature Format

The package generates unique signatures for each exception using:

Format: ExceptionClass:FilePath:LineNumber
Example: Exception:app/Http/Controllers/UserController.php:45

This ensures:

  • โœ… Same exception at same location = same signature
  • โœ… Rate limiting works per unique error
  • โœ… Different locations = different signatures

๐Ÿ”’ Security

Preventing Infinite Loops

The package is designed to never break your application:

// In JsonExceptionHandler
try {
    $this->notifierService->notify($e);
} catch (Throwable $notificationError) {
    // Silently fail if notification fails
    Log::error('Exception notification failed', [
        'error' => $notificationError->getMessage(),
    ]);
}

Bot Protection

Automatically ignores exceptions from bots to prevent spam:

'ignored_bots' => [
    'googlebot', 'bingbot', 'slurp', 'crawler', 'spider',
    'bot', 'facebookexternalhit', 'twitterbot', 'whatsapp',
    'telegram', 'curl', 'wget',
],

๐Ÿค Contributing

Contributions are welcome! Please see CONTRIBUTING.md for details.

Development Setup

# Clone the repository
git clone https://github.com/damku999/exception-notifier.git
cd exception-notifier

# Install dependencies
composer install

# Run tests
composer test

# Run code style checks
composer lint

๐Ÿ“ Changelog

Please see CHANGELOG.md for recent changes.

๐Ÿ“„ License

The MIT License (MIT). Please see LICENSE.md for more information.

๐Ÿ™ Credits

  • Author: Darshan Baraiya
  • GitHub: @damku999
  • Built with: Laravel 12, PHP 8.2

๐Ÿ’ก Use Cases

Perfect for:

  • ๐Ÿข Production Applications - Monitor critical production errors
  • ๐Ÿ”ง Staging Environments - Catch bugs before production
  • ๐Ÿ“Š API Services - Track API failures and exceptions
  • ๐Ÿš€ Microservices - Centralized exception monitoring
  • ๐Ÿ‘ฅ Team Collaboration - Multiple developers receive alerts

๐Ÿ†˜ Support

Developed by Darshan Baraiya