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

Backtrace Laravel Package

spatie/backtrace

Spatie Backtrace provides a cleaner, easier-to-use alternative to PHP’s debug_backtrace. It returns a structured list of Frame objects with accurate file, line, class/method info, and optional arguments, making traces simpler to inspect and filter.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require spatie/backtrace
    

    No configuration is required—just start using it immediately.

  2. First Use Case: Replace debug_backtrace() with Spatie\Backtrace\Backtrace::create()->frames() for cleaner, more readable frame data:

    use Spatie\Backtrace\Backtrace;
    
    $frames = Backtrace::create()->frames();
    $firstFrame = $frames[0];
    
    echo "File: {$firstFrame->file}\n";
    echo "Line: {$firstFrame->lineNumber}\n";
    echo "Class: {$firstFrame->class}\n";
    
  3. Key Starting Points:

    • Laravel Integration: Use applicationPath(base_path()) to filter vendor/application frames.
    • Error Handling: Use Backtrace::createForThrowable($exception) for exceptions.

Implementation Patterns

Core Workflows

  1. Basic Frame Inspection:

    $backtrace = Backtrace::create();
    foreach ($backtrace->frames() as $frame) {
        if ($frame->class === MyService::class) {
            log("Found MyService at {$frame->file}:{$frame->lineNumber}");
        }
    }
    
  2. Filtering Frames:

    • By Class/Method:
      $frames = Backtrace::create()
          ->startingFromFrame(fn($frame) => $frame->class === Controller::class)
          ->frames();
      
    • By Offset:
      $frames = Backtrace::create()->offset(2)->frames(); // Skip first 2 frames
      
  3. Laravel-Specific Patterns:

    $backtrace = Backtrace::create()
        ->applicationPath(base_path())
        ->trimFilePaths(); // Shortens paths (e.g., `app/Http/Controllers/...` instead of full path)
    
  4. Exception Handling:

    try {
        // Risky code
    } catch (Exception $e) {
        $frames = Backtrace::createForThrowable($e);
        // Log or display $frames for debugging
    }
    
  5. Argument/Object Inspection (Performance Note: Enable only when needed):

    $backtrace = Backtrace::create()
        ->withArguments()
        ->withObject()
        ->reduceArguments(); // Convert complex args (e.g., DateTime) to strings
    

Integration Tips

  • Logging: Use trimFilePaths() + applicationPath() to make logs cleaner.
  • Error Pages: Display filtered backtraces in custom exception handlers (e.g., Laravel’s App\Exceptions\Handler).
  • Testing: Mock Backtrace::create() in unit tests to simulate call stacks:
    $mockFrames = [new Frame(...), new Frame(...)];
    $this->app->instance(Backtrace::class, fn() => new Backtrace($mockFrames));
    

Gotchas and Tips

Pitfalls

  1. Performance Overhead:

    • withArguments()/withObject(): Disables PHP’s zend.exception_ignore_args temporarily. Use sparingly in production.
    • Solution: Cache backtraces or use only for debugging.
  2. Path Trimming Edge Cases:

    • trimFilePaths() requires applicationPath() to be set first.
    • Fix: Always chain ->applicationPath(base_path()) before ->trimFilePaths().
  3. Vendor/Application Frame Misclassification:

    • Laravel’s artisan and Statamic’s please are treated as vendor files (even if in root).
    • Workaround: Manually filter these frames if needed:
      $frames = Backtrace::create()->frames()->filter(fn($frame) => $frame->file !== base_path('artisan'));
      
  4. Closure/Serializable Objects:

    • Arguments for closures or non-serializable objects may appear as null or [object].
    • Tip: Use reduceArguments() to customize display for complex types.
  5. open_basedir Restrictions:

    • If a frame’s file is outside open_basedir, getSnippetAsString() may fail.
    • Fix: Handle exceptions gracefully:
      try {
          $snippet = $frame->getSnippetAsString();
      } catch (Exception $e) {
          $snippet = "Snippet unavailable (file outside open_basedir)";
      }
      

Debugging Tips

  1. Inspect Frame Properties:

    dd($frame->toArray()); // Dump all properties for debugging
    
  2. Custom Argument Reducers:

    • Override default reducers for domain-specific types (e.g., Carbon instances):
      $backtrace = Backtrace::create()
          ->withArguments()
          ->reduceArguments([
              new class implements ArgumentReducer {
                  public function execute($arg): ReducedArgumentContract {
                      return $arg instanceof Carbon
                          ? new ReducedArgument($arg->toDateTimeString(), get_class($arg))
                          : UnReducedArgument::create();
                  }
              }
          ]);
      
  3. Laravel Artisan Commands:

    • Use ->applicationPath(base_path()) to correctly classify frames in CLI commands.
  4. Testing Backtraces:

    • Unit Tests: Use Backtrace::create() directly to avoid real call stacks:
      $backtrace = Backtrace::create();
      $backtrace->setFrames([new Frame(...)]); // Inject mock frames
      

Extension Points

  1. Custom Frame Filtering:

    • Extend Spatie\Backtrace\Frame or use startingFromFrame() for complex logic:
      $backtrace->startingFromFrame(fn($frame) =>
          str_contains($frame->file, 'app/Http') && $frame->class !== Controller::class
      );
      
  2. Snippet Customization:

    • Override getSnippetAsString() in a custom Frame class to highlight specific syntax.
  3. Argument Reducers:

    • Implement ArgumentReducer for domain-specific types (e.g., Illuminate\Support\Collection).
  4. Laravel Service Provider:

    • Bind a global Backtrace instance with default settings:
      $this->app->singleton(Backtrace::class, fn() =>
          Backtrace::create()
              ->applicationPath(base_path())
              ->trimFilePaths()
      );
      
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.
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
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope
anil/file-picker
broqit/fields-ai