Search code examples
phplaravelhttpexceptioncoding-style

Laravel: Where to throw HTTP Exceptions


Background

Within PHP / Laravel MVC applications response codes and bodies are often dictated by the Exception that is thrown. If a HTTP exception is thrown (inheriting from Symfony\Component\HttpKernel\Exception\HttpException) the correct response codes are thrown (and in certain cases JSON responses). There are other types of exceptions that are non-http related as well that can be thrown.

Question

Where should HTTP exceptions be thrown?

  • A Only the controller
  • B Anywhere. Deep or shallow in the applications stack.

Should I be catching my exceptions in the controller and throwing HTTP versions of those exceptions? Or should I just throw a HTTP exception anywhere deep within a service class, repository or utility considering 99% of MVC framework apps are based around a HTTP request >> response lifecycle anyway?


Solution

  • My answer is not targeted at Laravel as I feel working with a framework mindset actually goes against your initial question.

    Always throw a tailored exception and then handle the conversion within the controller. In this case wrap it in a HttpException. There are a few good reasons for this:

    • The decision on which status code and message is delegated to the implementation (in this case the integration with your framework). This means that you could drop your code in any framework and handle its errors separately.
    • You decide you need a CLI command/worker and now your HttpException throws in your service make no sense to your CLI command.

    Essentially thinking about a calculator, it would throw a DivisionByZeroException. For a controller you would wrap this in a HttpException 400 BAD REQUEST and re-throw. For the CLI your command could just let the exception render on screen Division By Zero. Either way this decision is not made by your service.