Exception Factories for better code
Tags: laravel, php, cleancode, exceptions
Published: 2019-09-11 15:43:07

---
title: Exception Factories for better code
published: true
description: Programming tip for better code. Refactoring Exception constructors into factory methods.
tags: laravel, php, clean code, exceptions
cover_image: https://thepracticaldev.s3.amazonaws.com/i/ynnwkzckzadp4lkv51ek.jpg
---

Yes, Exception factories... Although I think it has been shared many times over the web. Today, I was making a code review and found out a good use case for "Exception Factories", so I think it is worth it to share this programming tip with you.

The code I was reviewing had somewhere in a method this:

```php
public function user(){
    ...
 
    $token = $this->getToken();
    $siteCredential = $this->getSiteCredential();
    
    throw_if(empty($token),
        AuthenticationException::class,
        __('auth.failed', ['code' => AuthenticationCodes::TOKEN_NOT_PROVIDED]), 401);

    throw_if(is_null($siteCredential),
        AuthenticationException::class,
        __('auth.failed', ['code' => AuthenticationCodes::CREDENTIALS_NOT_FOUND]), 401);

    throw_if($siteCredential->hasExpired(),
        AuthenticationException::class,
        __('auth.failed', ['code' => AuthenticationCodes::CREDENTIALS_EXPIRED]), 401);

    throw_if(! optional($siteCredential->site)->isEnabled(),
        AuthenticationException::class,
        __('auth.failed', ['code' => AuthenticationCodes::SITE_DISABLED]), 401);
    ...
}

```

The code works fine, don't get me wrong about this, the thing I am trying to achieve with this refactor is to make this code a bit more readable and clean. As you can see each `Exception` is conditionally thrown making use of a multiline expression in php, these long expressions might become not so eye-friendly when reading code.

Whenever I reach situations like this, I like to refactor them into "Exception Factory Methods". We can see that every thrown exception is an `AuthenticationException` so it makes sense to work inside the class itself, we will introduce one (or many) new `static` methods that will handle the "construction" of the exception. 

After refactoring, the `AuthenticationException` class looks like this:

```php
class AuthenticationException extends Exception
{
    protected $httpStatusCode = 401;

    public static function forCode(string $code): self
    {
        return new self(__('auth.failed', ['code' => $code]));
    }

    public static function forTokenNotFound(): self
    {
        return self::forCode(AuthenticationCodes::TOKEN_NOT_PROVIDED);
    }

    public static function forCredentialsNotFound(): self
    {
        return self::forCode(AuthenticationCodes::CREDENTIALS_NOT_FOUND);
    }

    public static function forCredentialsExpired(): self
    {
        return self::forCode(AuthenticationCodes::CREDENTIALS_EXPIRED);
    }

    public static function forSiteDisabled(): self
    {
        return self::forCode(AuthenticationCodes::SITE_DISABLED);
    }

```

Now we can clean up our initial `user()` method to use our factory methods:


```php
public function user(){
    ...
 
    $token = $this->getToken();
    $siteCredential = $this->getSiteCredential();
    
    if (empty($token)) {
        throw AuthenticationException::forTokenNotFound();
    }

    if (is_null($siteCredential)) {
        throw AuthenticationException::forCredentialsNotFound();
    }

    if ($siteCredential->hasExpired()) {
        throw AuthenticationException::forCredentialsExpired();
    }

    if (is_null($siteCredential->site) || $siteCredential->site->isDisabled()) {
        throw AuthenticationException::forSiteDisabled();
    }
    ...
}

```

I think it makes the code a little bit more expressive and readable. 

Share what you think!!