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.
- β¨ Laravel 12+ Support - Modern
bootstrap/app.phppattern - β¨ 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.
- π¨ 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
- PHP 8.2 or higher
- Laravel 12.0 or higher
- Mail configuration (SMTP, Mailgun, SES, etc.)
Install the package via Composer:
composer require damku999/exception-notifierPublish the configuration file:
php artisan vendor:publish --tag="exception-notifier-config"This will create config/exception_notifier.php with all available options.
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/.
If you want to use database-backed rate limiting:
php artisan vendor:publish --tag="exception-notifier-migrations"
php artisan migrateAdd 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=3600Update 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();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,
];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 emailYou can manually trigger exception notifications:
use Damku999\ExceptionNotifier\Facades\ExceptionNotifier;
try {
// Your code
} catch (\Throwable $e) {
ExceptionNotifier::notify($e);
// Continue with your error handling
}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();View current rate limit status for all exception signatures:
php artisan exception:rate-limit-statusOutput:
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ¬ββββββββ¬ββββββ¬βββββββββββ
β 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 all rate limits:
php artisan exception:clear-rate-limitsClear specific signature:
php artisan exception:clear-rate-limits --signature="Exception:app/Http/Controllers/UserController.php:45"Send a test exception email:
php artisan exception:testSend test with custom exception type:
php artisan exception:test --type=criticalThe package includes two beautiful, responsive email templates:
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
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
Publish the views and edit them:
php artisan vendor:publish --tag="exception-notifier-views"Templates location: resources/views/vendor/exception-notifier/
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',
],
]);Run the test suite:
composer testRun tests with coverage:
composer test:coverageThe 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
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(),
]);
}Automatically ignores exceptions from bots to prevent spam:
'ignored_bots' => [
'googlebot', 'bingbot', 'slurp', 'crawler', 'spider',
'bot', 'facebookexternalhit', 'twitterbot', 'whatsapp',
'telegram', 'curl', 'wget',
],Contributions are welcome! Please see CONTRIBUTING.md for details.
# 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 lintPlease see CHANGELOG.md for recent changes.
The MIT License (MIT). Please see LICENSE.md for more information.
- Author: Darshan Baraiya
- GitHub: @damku999
- Built with: Laravel 12, PHP 8.2
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
- π Documentation
- π Issue Tracker
- π¬ Discussions
Developed by Darshan Baraiya