No throw and happier life


2 min read

Hi guys,

Let's talk about a coding approach today.

The throw is really familiar, especially for OOP languages, right?

Basically, when something goes wrong, developers throw an Exception/Error. And that's all. Not that big of a deal, right?

But why did I put the title as "No throw"? Well, everything has its reason, isn't it?

Let's talk about it.

Abusing Exceptions

Exception, well, the name says it all.

You only throw an Exception when you encounter an unexpected error (from anything).

But nowadays, people always throw on everything, even a simple error. That's not a good approach.

When you throw an Exception, you expect the one who reuses your libraries/services/... will wrap the invoking in try/catch. But not everybody would know and add that => That's where Error happens in Production.

You always end up in the try/catch scope from everywhere in your code. Well, looks to me, like it doesn't bring any confidence & reliability. Especially catch (Throwable), lol.

I've seen a case from a developer whose code was throwing the exception in the "binding/DI-resolve" process and a whole application went down.

Let's just don't overuse/abuse the Exceptions. They should only be used on "unexpected" things only.

Let's talk about another approach.

Simple OK/Error Response

Well, simply return things like:

  • OK: return ID or some data

  • Error: return null

Even a simple boolean to let other developers know, when they reuse something, based on the return type, they can know the outcome in seconds.

More complex? Check out PHP NeverThrow

You'll create OK & Error result class based on your business logic. Eg:

  • BookingOkResult

    • bookingId
  • BookingErrorResult

    • outcome (enum)

      • Order is invalid

      • Booking timeout

      • Insufficient balance

      • ...

Then, everywhere that invokes your method, they can check the response and do the wanted things, eg:

$bookingResult = $this->service->createBooking($user, $order);

if ($bookingResult->isError()) {
    // handle error
    return showError(match ($bookingResult->getErrorResult()->outcome) {
        'INSUFFICIENT_BALANCE' => 'Not enough balance to make the booking',
        'ORDER_IS_INVALID' => 'The order is invalid (probably expired)',

return showBooking($bookingResult->getOkResult()->bookingId);

You see, no throw, only simple OK/Error checking.

It increases the development productivity skyrocketing. Developers don't have to worry about things when they reuse something. Keep everything DRY,...


Like the title said, No throws = happier life (and not just you).

Thanks for reading!