Filament Exceptions

repository·main·Indexed 41 days ago

https://github.com/bezhansalleh/filament-exceptions

A simple exception viewer for the FilamentPHP admin panel that automatically records exceptions and provides a centralized interface for developers to inspect them. It includes features for conditional recording via the FilamentExceptions facade, custom exception model support, and automated pruning of old records.

Tokens
5.6K
Snippets
21
Records
29
Agent score
52%

What's inside Filament Exceptions

  1. Install filament-exceptions

    main

    Follow these steps to integrate the exception viewer into your FilamentPHP admin panel:

    1. Install the package via Composer:
      composer require bezhansalleh/filament-exceptions
    2. Publish and run the migrations:
      php artisan exceptions:install
    3. Register the plugin in your Filament Panel provider:
      public function panel(Panel $panel): Panel
      {
          return $panel
              ->plugins([
                  \BezhanSalleh\FilamentExceptions\FilamentExceptionsPlugin::make()
              ]);
      }

    Important: Theming To ensure the plugin follows your Filament theme, add the following line to your theme.css file and rebuild your assets:

    @source '../../../../vendor/bezhansalleh/filament-exceptions/resources/views/**/*.blade.php';
    npm run build
    composer require bezhansalleh/filament-exceptions
    php artisan exceptions:install
  2. Use a custom exception model

    main

    If you want to use a custom database model for storing exceptions, follow these two steps:

    1. Create a model that extends the base exception model:

      namespace App\
      Models;
      
      use BezhanSalleh\\FilamentExceptions\\Models\\Exception as BaseException;
      
      class MyCustomException extends BaseException
      {
          // Your custom logic here
      }
    2. Register your custom model in your AppServiceProvider::boot() method:

      use App\
      Models\\MyCustomException;
      use BezhanSalleh\\FilamentExceptions\\FilamentExceptions;
      
      public function boot()
      {
          FilamentExceptions::model(MyCustomException::class);
      }
    // 1. Extend the base model
    class MyCustomException extends \BezhanSalleh\FilamentExceptions\Models\Exception {}
    
    // 2. Register it in AppServiceProvider
    FilamentExceptions::model(MyCustomException::class);
  3. Understand the StoredException class

    main
    The StoredException class is a wrapper that provides an interface compatible with Laravel's exception renderer. It is used to transform a database record (from the ExceptionModel) into a structured object that can be used to display historical exception data in a UI. It reconstructs the context of the error, including the request, stack trace, route parameters, and database queries, even if the original exception is no longer in memory.
  4. Configure FilamentExceptionsPlugin options

    main

    When registering the plugin, you can chain methods to customize its appearance and behavior.

    • navigationBadge(bool | Closure $condition = true)
    • navigationBadgeColor(string | array | Closure $color)
    • navigationGroup(string | Closure | null $group)
    • navigationParentItem(string | Closure | null $item)
    • navigationIcon(string | Closure | null $icon)
    • activeNavigationIcon(string | Closure | null $icon)
    • navigationLabel(string | Closure | null $label)
    • navigationSort(int | Closure | null $sort)
    • registerNavigation(bool | Closure $shouldRegisterNavigation)
    • subNavigationPosition(SubNavigationPosition | Closure $position)
    • modelLabel(string | Closure | null $label)
    • pluralModelLabel(string | Closure | null $label)
    • titleCaseModelLabel(bool | Closure $condition = true)
    • globallySearchable(bool | Closure $condition = true)

    Mass Pruning

    • modelPruneInterval(Carbon $interval): Sets the interval for pruning old exceptions. Note: Requires Laravel's scheduler to be configured.

    Tenancy

    • scopeToTenant(bool | Closure $condition = true)
    • tenantOwnershipRelationshipName(string | Closure | null $ownershipRelationshipName)
    • tenantRelationshipName(string | Closure | null $relationshipName)

    General

    • cluster(string | Closure | null $cluster)
    • slug(string | Closure | null $slug)
    FilamentExceptionsPlugin::make()
        ->navigationLabel('Error Logs')
        ->navigationIcon('heroicon-o-bug-ant')
        ->navigationBadge()
        ->navigationGroup('System')
        ->modelPruneInterval(now()->subDays(7))
  5. Automated exception reporting

    main
    The package automatically hooks into Laravel's ExceptionHandler. When an exception occurs, the package checks if the exception should be reported using Laravel's standard shouldReport() logic. If it should, the package automatically records the exception using FilamentExceptions::report($e). This ensures that all relevant exceptions are captured in the database for viewing within the Filament UI without manual intervention in your application code.
  6. Install the Filament Exceptions plugin

    main

    Run the exceptions:install command to set up the Filament Exceptions plugin. This command automatically publishes the necessary migrations using the filament-exceptions-migrations tag and executes the database migrations.

    If you need to overwrite existing files or force the migration process, use the --force flag.

    php artisan exceptions:install
    
    # To force overwrite files and migrations
    php artisan exceptions:install --force
  7. Register the Filament Exceptions plugin

    main

    To integrate the exception viewer into your Filament panel, use the FilamentExceptionsPlugin::make() method within your panel configuration. This registers the ExceptionResource and sets up the necessary plugin infrastructure.

    use BezhanSallehilament-exceptions\FilamentExceptionsPlugin;
    
    public function panel(Panel $panel): Panel
    {
        return $panel
            // ... other configuration
            ->plugins([
                FilamentExceptionsPlugin::make(),
            ]);
    }
  8. Install filament-exceptions via Artisan command

    main

    The package includes an InstallCommand which can be used to set up the necessary components. While the specific command name is typically handled by the package's internal installer, the presence of InstallCommand in the service provider indicates that an installation command is available to automate the setup process (migrations, views, etc.).

    php artisan filament-exceptions:install
  9. Control exception recording behavior

    main

    You can manage how and when exceptions are recorded using the FilamentExceptions class within your AppServiceProvider::boot() method.

    Stop/Start Recording

    Use these methods to globally enable or disable recording:

    • FilamentExceptions::stopRecording(): Stops recording exceptions.
    • FilamentExceptions::startRecording(): Resumes recording.
    • FilamentExceptions::isRecording(): Checks the current recording status.

    Conditional Recording

    Use recordUsing() to define custom logic. The callback can return a boolean or accept a Throwable $e to decide whether to record a specific exception.

    Examples:

    • Record only in production: FilamentExceptions::recordUsing(fn () => app()->isProduction());
    • Skip specific types: Skip ValidationException or AuthenticationException.
    • Complex logic: Skip 4xx HTTP exceptions while recording everything else in production.
    use BezhanSallehilament-exceptions\FilamentExceptions;
    
    public function boot(): void
    {
        // Only record in production
        FilamentExceptions::recordUsing(fn () => app()->isProduction());
    
        // Skip specific exception types
        FilamentExceptions::recordUsing(function (Throwable $e) {
            return ! $e instanceof \Illuminate\Validation\ValidationException
                && ! $e instanceof \Illuminate\Auth\AuthenticationException;
        });
    }
  10. Generate markdown representation of a StoredException

    main

    The markdown() method returns a string containing a full markdown report of the exception. If a markdown version was not explicitly stored in the database, the class will dynamically generate one containing:

    • Exception class and title
    • Message, PHP version, and Laravel version
    • Hostname
    • Stack Trace (file and line numbers)
    • Request method and path
    • Headers
    • Route Context and Parameters
    • Database Queries
  11. Use the FilamentExceptions facade to manage exception recording

    main

    The FilamentExceptions facade provides a static interface to control how exceptions are captured and stored. You can manually start or stop the recording process, check the current recording status, or define a custom callback for how exceptions are recorded.

    use BezhanSalleh\FilamentExceptions\Facades\FilamentExceptions;
    
    // Start recording exceptions
    FilamentExceptions::startRecording();
    
    // Check if recording is active
    if (FilamentExceptions::isRecording()) {
        // ...
    }
    
    // Stop recording
    FilamentExceptions::stopRecording();
    
    // Define a custom recording logic via a closure
    FilamentExceptions::recordUsing(function (Throwable $exception) {
        // Custom logic here
    });