Weave Code
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

Mail Exception Bundle Laravel Package

desarrolla2/mail-exception-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps for Laravel Integration

  1. Install Dependencies (if using Symfony Mailer):
    composer require symfony/mailer symfony/mime
    
  2. Create a Custom Exception Handler Extension: Extend Laravel’s App\Exceptions\Handler to send emails on uncaught exceptions:
    // app/Exceptions/Handler.php
    use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
    use Illuminate\Support\Facades\Mail;
    use App\Mail\ExceptionEmail;
    
    class Handler extends ExceptionHandler
    {
        public function report(Throwable $exception)
        {
            if (!$this->shouldSendExceptionEmail($exception)) {
                return parent::report($exception);
            }
            Mail::to(config('mail-exception.to'))
                ->send(new ExceptionEmail($exception));
        }
    
        protected function shouldSendExceptionEmail(Throwable $exception): bool
        {
            $ignoredEnvironments = config('mail-exception.avoid.environments', []);
            $ignoredExceptions = config('mail-exception.avoid.exceptions', []);
    
            return !in_array(app()->environment(), $ignoredEnvironments)
                && !in_array(get_class($exception), $ignoredExceptions);
        }
    }
    
  3. Create the Email Template:
    php artisan make:mail ExceptionEmail
    
    // app/Mail/ExceptionEmail.php
    public function build()
    {
        return $this->subject(config('mail-exception.subject'))
            ->markdown('emails.exception')
            ->with([
                'exception' => $this->exception,
                'request' => request(),
            ]);
    }
    
  4. Configure in .env:
    MAIL_EXCEPTION_FROM=your@email.com
    MAIL_EXCEPTION_TO=your@email.com
    MAIL_EXCEPTION_SUBJECT="An error has occurred"
    MAIL_EXCEPTION_AVOID_ENVIRONMENTS="dev,test"
    MAIL_EXCEPTION_AVOID_EXCEPTIONS="Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException,Symfony\Component\HttpKernel\Exception\NotFoundHttpException"
    
  5. Publish Config (Optional):
    php artisan vendor:publish --provider="App\Providers\MailExceptionServiceProvider"
    
    (Create a service provider if needed to load config.)

First Use Case: Debugging Production Errors

  • Scenario: A 500 Internal Server Error occurs in production due to an unhandled exception.
  • Outcome: The configured email recipient receives a formatted email with:
    • Exception type and message.
    • Stack trace.
    • Request details (URL, headers, POST data).
    • Environment context (e.g., production).
  • Action: Developer investigates the issue using the provided context, reducing debugging time.

Implementation Patterns

Core Workflow

  1. Exception Handling:
    • Laravel’s ExceptionHandler catches uncaught exceptions via report().
    • Override report() to conditionally send emails (based on config).
  2. Email Dispatch:
    • Use Laravel’s Mail facade to send structured emails.
    • Include exception details in the email body (plaintext or Markdown).
  3. Configuration:
    • Store settings in .env or config/exception.php:
      'mail-exception' => [
          'from' => env('MAIL_EXCEPTION_FROM'),
          'to' => env('MAIL_EXCEPTION_TO'),
          'subject' => env('MAIL_EXCEPTION_SUBJECT'),
          'avoid' => [
              'environments' => explode(',', env('MAIL_EXCEPTION_AVOID_ENVIRONMENTS', '')),
              'exceptions' => explode(',', env('MAIL_EXCEPTION_AVOID_EXCEPTIONS', '')),
          ],
      ],
      
  4. Environment Awareness:
    • Skip email alerts in dev/test environments:
      if (in_array(app()->environment(), config('mail-exception.avoid.environments'))) {
          return false;
      }
      

Integration Tips

1. Leverage Laravel’s Mail System

  • Use queued emails (Mail::later()) to avoid blocking requests:
    Mail::queue(new ExceptionEmail($exception));
    
  • Customize email templates with Markdown or Blade:
    <!-- resources/views/emails/exception.blade.php -->
    @component('mail::message')
        # Exception Occurred: {{ $exception->getMessage() }}
    
        **Type**: {{ get_class($exception) }}
    
        **Stack Trace**:
        ```
        {{ $exception->getTraceAsString() }}
        ```
    
        **Request**:
        - URL: {{ $request->fullUrl() }}
        - Method: {{ $request->method() }}
    
        @if($request->has('input'))
            **Input**: {{ $request->input() }}
        @endif
    @endcomponent
    

2. Extend for Advanced Use Cases

  • Add Attachments: Attach log files or screenshots:
    Mail::to(config('mail-exception.to'))
        ->attach(storage_path('logs/laravel.log'))
        ->send(new ExceptionEmail($exception));
    
  • Rate Limiting: Avoid email spam with throttle():
    use Illuminate\Cache\RateLimiter;
    
    $limiter = RateLimiter::for('exception-emails', function () {
        return Cache::forever('exception-emails');
    });
    
    if ($limiter->tooManyAttempts(1, 60)) {
        return false; // Skip if >1 email/minute
    }
    
  • Slack/Teams Integration: Forward emails to a webhook:
    $webhook = 'https://hooks.slack.com/...';
    $ch = curl_init($webhook);
    curl_setopt($ch, CURLOPT_POSTFIELDS, [
        'text' => "New exception: {$exception->getMessage()}",
    ]);
    curl_exec($ch);
    

3. Testing

  • Unit Test Email Dispatch:
    public function test_exception_email_is_sent()
    {
        $exception = new \RuntimeException('Test error');
        $this->expectException(\RuntimeException::class);
    
        Mail::fake();
        $this->report($exception);
    
        Mail::assertSent(ExceptionEmail::class);
    }
    
  • Mock External Services: Use Mail::fake() to verify emails are sent without hitting SMTP.

4. Performance Considerations

  • Async Processing: Queue emails to avoid delays:
    Mail::queue(new ExceptionEmail($exception));
    
  • Batch Exceptions: For high-volume apps, batch exceptions (e.g., send daily digests):
    // app/Console/Commands/SendExceptionDigest.php
    public function handle()
    {
        $exceptions = Exception::where('processed', false)->limit(50)->get();
        foreach ($exceptions as $exception) {
            Mail::to(config('mail-exception.to'))->send(new ExceptionDigest($exception));
            $exception->update(['processed' => true]);
        }
    }
    

Gotchas and Tips

Pitfalls

  1. Double Reporting:

    • Laravel’s ExceptionHandler already logs exceptions to storage/logs/laravel.log. Ensure emails don’t duplicate efforts:
      // Skip if already logged (e.g., by Monolog)
      if (Log::hasErrors()) {
          return false;
      }
      
    • Fix: Use Log::channel('single') to avoid duplicate logs.
  2. Sensitive Data Leaks:

    • Emails may include request payloads with PII (e.g., passwords, tokens).
    • Fix: Redact sensitive fields:
      $requestData = $request->except(['password', 'api_token', 'cc_number']);
      
    • Use Laravel’s Illuminate\Support\Str::mask() for partial redaction.
  3. Environment Misconfiguration:

    • Accidentally sending emails in dev due to misconfigured .env:
      APP_ENV=production  # Ensure this is correct!
      
    • Fix: Add validation in shouldSendExceptionEmail():
      if (!in_array(app()->environment(), ['production', 'staging'])) {
          return false;
      }
      
  4. Email Delivery Failures:

    • SMTP misconfigurations or rate limits may cause silent failures.
    • Fix: Implement retry logic with Mail::later() or a job queue (e.g., Laravel Queues + Redis).
  5. Symfony-Specific Assumptions:

    • The original bundle assumes Symfony’s ExceptionListener. Laravel’s ExceptionHandler works differently:
      • Symfony: Listens to KernelEvents::EXCEPTION.
      • Laravel: Uses report()/render() in App\Exceptions\Handler.
    • Fix: Abstract the logic to avoid tight coupling.

Debugging Tips

  1. Verify Email Dispatch:
    • Check if emails are queued:
      php artisan queue:work
      
    • Inspect queued jobs:
      php artisan
      
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.
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle