Laravel's exceptions: Part 1 – What are exceptions?
Tags: php, laravel, programming, tutorial
Published: 2022-02-10 02:00:23

An exception is an event that occurs during the execution of a program that disrupts the normal flow of instructions. PHP uses exceptions to handle errors and other exceptional events.

As in many other languages, an exception can be thrown and caught. You can throw an exception using the `throw` keyword, which in PHP 8 became an expression that may be used in any expression context, while in previous versions it was a statement that had to be in its line.

To facilitate the catching of exceptions, the code should be surrounded by a `try` block that must have at least one matching `catch` or `finally` blocks. If an exception gets thrown and its current scope doesn’t have a catchable block, the exception will “bubble up” or be sent to a “higher scope”.

If the handling of an exception implements both the `catch` and `finally` blocks, be advised that all `finally` blocks encountered in the way of the exception event will be executed, even when the event has already passed through the `catch` block.

Finally, if an exception goes all the way to the global scope without finding a matching catchable block, your code will terminate with a fatal error unless the app has a global exception handler, like the one that Laravel has.

### Content
- [Throwing exceptions](#throwing-exceptions)
- [The try and catch blocks](#the-try-and-catch-block)
- [The finally block](#the-finally-block)

### Throwing exceptions

Now that we understand the structure around exception events, let’s see a couple of examples of how we can throw and catch exceptions.

Let’s say we want to parse a PHP object to JSON; we would probably use the `json_encode()` function for that. This function will not always be able to transform the given object to JSON for various reasons, and when this happens, the function will return `false` to let us know that the transformation failed.

In some ways, we can say that if the transformation of the object fails, our code gets disrupted from the normal flow of instructions since we instructed the code to get us a JSON, and we got a boolean instead.

With that being said, let’s see in the example down below, how we can use an exception to trigger an event informing that something out of the normal flow has happened.

```php
<?php

class Person
{
    private $props = [];

    public function __construct(
        private string $name = '',
        private string $lastName = ''
    ) {
        $this->props = [
            'name' => $this->name,
            'last_name' => $this->lastName,
        ];
    }

    public function toJson($options = 0.0)
    {
        $jsonEncoded = json_encode($this->props, $options);

        if ($jsonEncoded === false) {
            throw new JsonEncodeException();
        }

        return $jsonEncoded;
    }
}
```
The `toJson()` function is responsible for transforming his class into JSON; as mentioned before, we were going to use the `json_encode()` which is being called at the first line of the function and has its returned value stored at the `$jsonEncoded` object.

Next, we have a conditional that checks if the `$jsonEncoded` is `false`, and if it is, an exception will be thrown because the normal flow of our code got disrupted.

Then, if the flow of our code didn’t get disrupted, we would just return the `$jsonEncoded` object, which at this point is a JSON with the correspondent values of the props from our Person class.

### The try and catch blocks

To catch the exception potentially thrown by the Person class, we have to use a `try` with a matching `catch` block, as the example down below shows.

```php
try {
    $person = new Person('Jack', 'Miras');
    $personAsJson = $person->toJson();
} catch(JsonEncodeException $e) {
    echo "Exception has been caught";
}
```

On the first line of the `try` block, we are creating a person object, passing a name and a last name as parameters in its constructor.

Next, we call the `toJson()` function out of the `$person` object. If the object got correctly transformed into JSON, the `$personAsJson` object would receive a JSON string as a result. Otherwise, an exception would be thrown, and the `catch` block would be triggered.

Thereafter, if an exception gets thrown and the `catch` block gets triggered, it would first check if the exception being intercepted is an instance of the JsonEncodeException class. If that’s the case, the `catch` block would take this exception event, passing it to its handling block, which is printing a message telling that the exception has been caught.

### The finally block

Another way of handling the exception potentially thrown by the Person class would be to use a `finally` block to match the `try` block defined, as the example below shows.

```php
try {
    $person = new Person('Jack', 'Miras');
    $personAsJson = $person->toJson();
} finally {
    echo "Converting person to JSON failed";
}
```

As in the previous example, at the `try` block, we are creating a person object and calling the `toJson()` function out of it. If the object gets correctly transformed, the `$personAsJson` would receive a JSON string. Otherwise, an exception would be thrown.

Thereafter, if an exception gets thrown, the `finally` block will be triggered even though a catch block has already handled the exception event.

If that’s the case, the `finally` block would take in this exception event and print a message telling that the conversion of the person object into JSON failed.

___

Now that you have a more in-depth understanding of what exceptions are and what they are used for, it’s time for us to move on to the next post in this series.

Happy coding!