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

Exceptions Bundle Laravel Package

dosfarma/exceptions-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation Add the bundle via Composer:

    composer require dosfarma/exceptions-bundle
    

    Register the bundle in config/bundles.php (Symfony) or config/app.php (Laravel via Symfony bridge):

    return [
        // ...
        DosFarma\ExceptionsBundle\DosFarmaExceptionsBundle::class => ['all' => true],
    ];
    
  2. First Use Case Throw an exception in your controller or service:

    use DosFarma\Exceptions\ApiException;
    
    throw new ApiException('Invalid request', 40001123);
    

    The bundle automatically converts it to a JsonResponse with the specified structure.

  3. Where to Look First

    • Configuration: Check config/packages/dosfarma_exceptions.yaml (Symfony) or config/exceptions.php (Laravel).
    • Customization: Override the ApiResponseLoader service (see below).
    • Exceptions: Review src/Exception/ApiException.php for available exception types.

Implementation Patterns

Core Workflow

  1. Throwing Exceptions Use ApiException for API-specific errors:

    throw new ApiException('User not found', 404001, ['user_id' => $request->user_id]);
    

    The payload will include:

    {
      "message": "User not found",
      "error_code": 404001,
      "details": { "user_id": 123 }
    }
    
  2. Customizing Responses Extend the default ApiResponseLoader to modify the JSON structure:

    namespace App\Service;
    
    use DosFarma\ExceptionsBundle\Http\Service\ApiResponseLoader as BaseLoader;
    use Symfony\Component\HttpFoundation\JsonResponse;
    
    class CustomApiResponseLoader extends BaseLoader
    {
        public function createResponse(string $message, int $errorCode, array $details = []): JsonResponse
        {
            return new JsonResponse([
                'status' => 'error',
                'code' => $errorCode,
                'message' => $message,
                'data' => $details,
                'timestamp' => now()->toIso8601String(),
            ]);
        }
    }
    

    Register it in config/services.yaml (Symfony) or config/app.php (Laravel):

    services:
        DosFarma\ExceptionsBundle\Http\Service\ApiResponseLoader:
            class: App\Service\CustomApiResponseLoader
    
  3. Integration with Laravel If using Laravel, create a service provider to bind the bundle’s services:

    namespace App\Providers;
    
    use Illuminate\Support\ServiceProvider;
    use DosFarma\ExceptionsBundle\Http\Service\ApiResponseLoader;
    
    class ExceptionsServiceProvider extends ServiceProvider
    {
        public function register()
        {
            $this->app->singleton(ApiResponseLoader::class, function ($app) {
                return new \App\Service\CustomApiResponseLoader();
            });
        }
    }
    
  4. Handling Non-API Exceptions For non-API routes, exclude the listener by tagging the controller:

    #[Route('/non-api', name: 'non_api_route', methods: ['GET'])]
    class NonApiController extends AbstractController
    {
        public function __construct()
        {
            $this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');
        }
    }
    

    Or disable globally in config:

    dosfarma_exceptions:
        enabled: false
    

Gotchas and Tips

Pitfalls

  1. Double Exception Handling If using Laravel’s built-in exception handler (e.g., App\Exceptions\Handler), ensure it doesn’t interfere with the bundle’s ApiExceptionListener. Disable Laravel’s JSON responses for ApiException:

    public function render($request, Throwable $exception)
    {
        if ($exception instanceof \DosFarma\Exceptions\ApiException) {
            return parent::render($request, $exception); // Let the bundle handle it
        }
        // ... rest of your logic
    }
    
  2. HTTP Code Mismatch The bundle uses the error_code (e.g., 40001123) as the HTTP status code by default. Override this behavior in CustomApiResponseLoader:

    public function createResponse(string $message, int $errorCode, array $details = []): JsonResponse
    {
        $httpCode = $this->mapErrorCodeToHttpStatus($errorCode);
        return new JsonResponse(/* ... */, $httpCode);
    }
    
  3. Service ID Conflicts Ensure the service ID DosFarma\ExceptionsBundle\Http\Service\ApiResponseLoader is unique in your container. Avoid naming collisions with other bundles.

Debugging Tips

  1. Log Unhandled Exceptions Add a subscriber to log exceptions before the listener processes them:

    use Symfony\Component\HttpKernel\Event\ExceptionEvent;
    use Symfony\Component\HttpKernel\KernelEvents;
    
    $eventDispatcher->addListener(KernelEvents::EXCEPTION, function (ExceptionEvent $event) {
        if ($event->getThrowable() instanceof \DosFarma\Exceptions\ApiException) {
            \Log::error('API Exception', [
                'message' => $event->getThrowable()->getMessage(),
                'code' => $event->getThrowable()->getCode(),
            ]);
        }
    });
    
  2. Test the Listener Verify the listener is active by throwing an exception in a test:

    public function testApiExceptionHandling()
    {
        $this->expectException(\Symfony\Component\HttpKernel\Exception\HttpException::class);
        $this->throwException(new ApiException('Test', 500001));
        $this->assertResponseStatusCode(500); // Or custom HTTP code
    }
    

Extension Points

  1. Custom Exception Types Extend ApiException to add domain-specific logic:

    namespace App\Exception;
    
    use DosFarma\Exceptions\ApiException;
    
    class ValidationApiException extends ApiException
    {
        public function __construct(array $errors, int $code = 400000)
        {
            parent::__construct('Validation failed', $code, ['errors' => $errors]);
        }
    }
    
  2. Dynamic Error Codes Use a service to generate error codes dynamically:

    namespace App\Service;
    
    class ErrorCodeGenerator
    {
        public function generate(string $context, string $action): int
        {
            return hash('crc32b', "$context-$action") & 0xFFFFFFFF;
        }
    }
    

    Inject it into your exceptions:

    $errorCode = $this->errorCodeGenerator->generate('user', 'not_found');
    throw new ApiException('User not found', $errorCode);
    
  3. Localization Support Override the ApiResponseLoader to support localized messages:

    public function createResponse(string $message, int $errorCode, array $details = []): JsonResponse
    {
        $translator = $this->container->get('translator');
        $translatedMessage = $translator->trans($message);
        return new JsonResponse([
            'message' => $translatedMessage,
            // ...
        ]);
    }
    
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.
codifyo/ts-generator-bundle
andydefer/laravel-cluster
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
christhompsontldr/laravel-inky
spatie/mailcoach-vapor