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

Corner Laravel Package

paragonie/corner

Corner provides extended PHP exceptions/errors with richer context: helpful long-form messages, source code snippets around the failure, and support links. Inspired by Rust-style diagnostics, useful even outside UI error pages.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require paragonie/corner
    

    Ensure your project uses PHP 7.1+ (or PHP 5.4+ for v1.x).

  2. Basic Usage: Replace native exceptions with Corner\Exception or Corner\Error:

    use Corner\Exception;
    
    try {
        throw new Exception('Something went wrong');
    } catch (Exception $e) {
        echo $e->getHelpfulMessage(); // Detailed explanation
        echo $e->getSnippet();        // Surrounding code snippet
    }
    
  3. First Use Case: Replace Laravel’s default Handler to log/render Corner exceptions:

    // app/Exceptions/Handler.php
    use Corner\Exception;
    use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
    
    class Handler extends ExceptionHandler {
        public function render($request, Throwable $exception) {
            if ($exception instanceof Exception) {
                return response()->json([
                    'error' => $exception->getHelpfulMessage(),
                    'snippet' => $exception->getSnippet(),
                ]);
            }
            return parent::render($request, $exception);
        }
    }
    

Implementation Patterns

Core Workflows

  1. Custom Exception Hierarchy: Extend Corner\Exception for domain-specific errors:

    class DatabaseConnectionException extends Exception {
        public function getHelpfulMessage() {
            return "Database connection failed. Check your `.env` file for `DB_HOST`, `DB_PORT`, and `DB_PASSWORD`.";
        }
        public function getSupportLink() {
            return 'https://laravel.com/docs/database#configuration';
        }
    }
    
  2. Dynamic Snippets: Use getSnippet() to debug runtime issues:

    try {
        $user = User::findOrFail($id);
    } catch (ModelNotFoundException $e) {
        echo $e->getSnippet(2, 2); // Show 2 lines before/after the error
    }
    
  3. Logging Integration: Log Corner exceptions with context:

    use Illuminate\Support\Facades\Log;
    
    try {
        // Risky operation
    } catch (Exception $e) {
        Log::error($e->getHelpfulMessage(), [
            'snippet' => $e->getSnippet(),
            'support_link' => $e->getSupportLink(),
        ]);
    }
    
  4. API Responses: Return structured error payloads:

    return response()->json([
        'status' => 'error',
        'message' => $e->getHelpfulMessage(),
        'code' => $e->getCode(),
        'debug' => app()->isLocal() ? $e->getSnippet(3, 3) : null,
    ]);
    
  5. Middleware for Errors: Catch Corner\Error (non-exception errors) globally:

    // app/Http/Kernel.php
    protected $errorMiddleware = [
        \App\Http\Middleware\HandleCornerErrors::class,
    ];
    

Gotchas and Tips

Pitfalls

  1. Performance Overhead:

    • getSnippet() reads source files dynamically. Avoid calling it in hot paths (e.g., loops).
    • Cache snippets if used repeatedly (e.g., in CLI tools).
  2. PHP 8+ Compatibility:

    • Test with PHP 8.x. Some Throwable methods may behave differently.
    • Use parent::__construct() explicitly in custom exceptions to avoid deprecation warnings.
  3. Source File Access:

    • getSnippet() fails if:
      • The file is unreadable (e.g., permissions).
      • The file is outside the project root (e.g., vendor files).
    • Handle Corner\FileNotFoundException gracefully:
      try {
          $snippet = $e->getSnippet();
      } catch (FileNotFoundException $e) {
          $snippet = "Could not locate source file: {$e->getMessage()}";
      }
      
  4. Stack Trace Depth:

    • getSnippet($traceWalk) may return empty strings for deep stack traces.
    • Limit $traceWalk to avoid excessive file I/O.

Debugging Tips

  1. Inspect Stack Traces: Use getTraceAsString() as a fallback for complex errors:

    echo $e->getHelpfulMessage() ?: $e->getTraceAsString();
    
  2. Custom Error Templates: Override getHelpfulMessage() to include:

    • ASCII diagrams (e.g., for validation errors).
    • Environment-specific hints (e.g., "Run php artisan cache:clear").
  3. Testing: Mock getSnippet() in unit tests:

    $exception = $this->getMockBuilder(Exception::class)
        ->onlyMethods(['getSnippet'])
        ->getMock();
    $exception->method('getSnippet')->willReturn('mocked snippet');
    

Extension Points

  1. Add Metadata: Extend exceptions with custom properties:

    class ValidationException extends Exception {
        public function __construct(array $errors) {
            parent::__construct('Validation failed');
            $this->errors = $errors;
        }
        public function getHelpfulMessage() {
            return "Validation errors:\n" . print_r($this->errors, true);
        }
    }
    
  2. Localization: Support multiple languages in getHelpfulMessage():

    public function getHelpfulMessage() {
        return __($this->getMessage(), [], 'errors');
    }
    
  3. Integration with Laravel:

    • Use Corner exceptions in validate() rules:
      $validator->errors()->add('email', new EmailValidationException($email));
      
    • Override App\Exceptions\Handler to format Corner exceptions for the debugbar.
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.
besmartand-pro/php-quality-config
sentix/ai-chatbot
terminal42/code-quality-tools
codifyo/ts-generator-bundle
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity