Weave 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

Api Exception Bundle Laravel Package

m6web/api-exception-bundle

Symfony bundle that centralizes API exception handling and returns clean JSON responses. Supports configurable error formatting, stack traces, form validation errors, exception matching/mapping, logging, and environment-specific behavior.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation (Symfony2 only)

    composer require m6web/api-exception-bundle
    

    For Laravel: Skip this. Instead, manually create equivalent exception classes (see Implementation Patterns).

  2. First Use Case: Basic Exception Handling

    • Symfony2: Configure config.yml to map exceptions to JSON responses (see Variables).
    • Laravel: Override App\Exceptions\Handler to return JSON for all exceptions:
      use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
      use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
      
      class Handler extends ExceptionHandler {
          public function render($request, Throwable $exception) {
              if ($exception instanceof HttpExceptionInterface) {
                  return response()->json([
                      'error' => $exception->getMessage(),
                      'code' => $exception->getStatusCode(),
                      'status' => 'error'
                  ], $exception->getStatusCode());
              }
              return parent::render($request, $exception);
          }
      }
      
  3. Where to Look First

    • Symfony2: Resources/doc/usage.md (exception mapping) and Resources/doc/errors.md (custom error types).
    • Laravel: Focus on:
      • app/Exceptions/Handler.php (global exception handling).
      • app/Http/Controllers/Controller.php (for controller-specific logic).
      • Laravel’s validation error responses.

Implementation Patterns

Usage Patterns

  1. Standardized Error Responses

    • Symfony2: Use api_exception configuration to define error structures:
      # config.yml
      api_exception:
          default:
              code: 0
              message: "An error occurred"
              status: 500
      
    • Laravel: Create a trait for consistent JSON responses:
      // app/Traits/ApiResponder.php
      trait ApiResponder {
          protected function errorResponse($message, $code = 400, $errors = null) {
              return response()->json([
                  'error' => [
                      'message' => $message,
                      'code' => $code,
                      'details' => $errors,
                      'status' => 'error'
                  ]
              ], $code);
          }
      }
      
  2. Validation Errors

    • Symfony2: Extend ValidationException and configure in api_exception.match:
      api_exception:
          match:
              Symfony\Component\Validator\Exception\ConstraintViolationListException: validation
      
    • Laravel: Leverage built-in validation responses:
      // In a controller
      $validator = Validator::make($request->all(), [
          'email' => 'required|email',
      ]);
      if ($validator->fails()) {
          return $this->errorResponse('Validation failed', 422, $validator->errors());
      }
      
  3. Custom Exceptions

    • Symfony2: Create classes extending ApiException:
      use M6Web\ApiExceptionBundle\Exception\ApiException;
      
      class UserNotFoundException extends ApiException {
          public function __construct() {
              parent::__construct('User not found', 404);
          }
      }
      
    • Laravel: Extend Exception and implement toJson():
      class UserNotFoundException extends Exception {
          public function toJson() {
              return response()->json([
                  'error' => 'User not found',
                  'code' => 404,
                  'status' => 'error'
              ], 404);
          }
      }
      
  4. Stack Trace Control

    • Symfony2: Toggle via config:
      api_exception:
          debug: "%kernel.debug%"  # Shows stack trace in dev
      
    • Laravel: Use environment-based logic:
      // In Handler.php
      public function render($request, Throwable $exception) {
          $response = response()->json([
              'error' => $exception->getMessage(),
              'code' => $exception->getCode(),
              'trace' => app()->environment('local') ? $exception->getTrace() : null
          ]);
          return $response;
      }
      

Workflows

  1. API Development Workflow

    • Symfony2: Throw exceptions and let the bundle handle formatting.
    • Laravel:
      1. Throw custom exceptions (e.g., UserNotFoundException).
      2. Catch in Handler.php or controller.
      3. Return JSON via errorResponse() trait or response()->json().
  2. Debugging Workflow

    • Symfony2: Enable debug mode to expose stack traces.
    • Laravel: Use app()->environment('local') to conditionally include traces:
      $response->setData([
          'error' => $exception->getMessage(),
          'trace' => app()->isLocal() ? $exception->getTrace() : null
      ]);
      
  3. Testing Workflow

    • Symfony2: Use ApiExceptionBundle\Tests as a reference.
    • Laravel: Test exception responses with PHPUnit:
      public function test_user_not_found() {
          $exception = new UserNotFoundException();
          $response = $this->getExceptionResponse($exception);
          $response->assertStatus(404);
          $response->assertJson([
              'error' => 'User not found',
              'code' => 404
          ]);
      }
      

Integration Tips

  1. Laravel-Symfony Bridge

    • Use symfony/http-foundation for shared components:
      composer require symfony/http-foundation
      
    • Example: Convert Symfony’s JsonResponse to Laravel’s response:
      use Symfony\Component\HttpFoundation\JsonResponse;
      use Illuminate\Http\JsonResponse as LaravelJsonResponse;
      
      $symfonyResponse = new JsonResponse(['error' => 'test']);
      $laravelResponse = new LaravelJsonResponse(
          $symfonyResponse->getContent(),
          $symfonyResponse->getStatusCode()
      );
      
  2. Event-Driven Extensions

    • Symfony2: Use api_exception.event to listen for exception events.
    • Laravel: Dispatch custom events in Handler.php:
      use Illuminate\Support\Facades\Event;
      
      public function report(Throwable $exception) {
          Event::dispatch(new ExceptionOccurred($exception));
      }
      
  3. Configuration Management

    • Symfony2: Centralized in config.yml.
    • Laravel: Store in config/exceptions.php:
      return [
          'default' => [
              'code' => 0,
              'message' => 'An error occurred',
              'status' => 500,
          ],
          'match' => [
              'App\Exceptions\UserNotFoundException' => 404,
          ],
      ];
      

Gotchas and Tips

Pitfalls

  1. Symfony Dependency Hell

    • Issue: The bundle requires Symfony components (e.g., HttpKernel, EventDispatcher).
    • Fix: Abstract core logic into framework-agnostic classes or use Laravel’s equivalents.
  2. Configuration Overrides

    • Issue: Symfony’s YAML config may conflict with Laravel’s PHP arrays.
    • Fix: Merge configs manually or use a package like spatie/laravel-config-array.
  3. Stack Trace Exposure

    • Issue: Accidentally leaking sensitive data in production.
    • Fix: Always gate traces by environment:
      'trace' => app()->environment('local') ? $exception->getTrace() : null
      
  4. Validation Error Formatting

    • Issue: Symfony’s ConstraintViolationListException format differs from Laravel’s validator errors.
    • Fix: Normalize errors before returning:
      $errors = collect($validator->errors()->all())
          ->map(fn($error) => ['field' => 'email', 'message' => $error]);
      
  5. Middleware vs. Handler Conflicts

    • Issue: Double exception handling if both middleware and Handler.php process errors.
    • Fix: Use return parent::render() in Handler.php to avoid duplication.

Debugging

  1. Symfony2-Specific Issues

    • Debugging Tip: Use bin/console debug:exception to inspect mapped exceptions.
    • Laravel Workaround: Log exceptions in Handler.php:
      Log::error($exception->getMessage(), [
          'trace' => $exception->getTrace(),
          'file' => $exception->getFile(),
          'line' => $exception->getLine(),
      ]);
      
  2. Custom Exception Not Triggering

    • Symfony2: Ensure the exception is listed in `
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.
dakiquang/laravel-oauth-refresh-lock
woda/laravel-worktrees
dalefranks/ramasite
faghy/laracashbook
roundly-consulting/google-places-for-laravel
roundly-consulting/kubernetes-api-for-laravel
roundly-consulting/plausible-for-laravel
gvp/gvp-laravel-template
metasyncsite/laravel-metasync-client
roundly-consulting/onboarding-for-laravel
andydefer/laravel-notification
adachsoft/cli-process-tester
jhaskell13/laraflow
sebastienheyd/boilerplate-media-manager
ccast/tagixo-primix
pretendtrue/laravel-builder
sawmainek/laravel-scout-tntsearch-driver
tomshaw/laravel-calendar-table
dibakar/laravel-ownership
adachsoft/changelog-linter