DEV Community

Cover image for HOW TO DEAL WITH EXCEPTIONS IN LARAVEL
Pedro Pessoa
Pedro Pessoa

Posted on

HOW TO DEAL WITH EXCEPTIONS IN LARAVEL

Laravel is a free and open-source PHP web framework, created by Taylor Otwell and intended for the development of web applications, Laravel is based on Symfony (wiki).

The Framework provides a lot of features to help developers improve the error handling avoinding your application returns an unexpected errors, in this post you can learn more about how to deal with exceptions in laravel.

 

Exceptions

You may be asking "how can i deal with errors better than a simple try catch block code?"

public function index()
{
    try {
        //do anything...
    } catch(ExampleException $exception) {
        return response()->json([
            'error' => 'An error occurred.'
        ], 500);
    }
}
Enter fullscreen mode Exit fullscreen mode

The above code is the most commun way that people deal with exceptions and it is not wrong, but it can be better, you can notice that the code is not the most secure way, if the ExampleException dispatches in elsewhere in the code you may add the try catch block in every place that the exception can be thrown, and sometimes you just don't know where it can be dispatched, but, what if there was a way to catch the exception regardless of where it is thrown?

 

Laravel Error Handling

There is a way to deal with any and all exceptions that your code raises and add logs, also send error reports to the cloud/email, thus having greater freedom to deal with errors in your system, allowing you to be aware of any error your project triggers in any code flow. Starting with version 11 of Laravel, it is possible to access the bootstrap/app.php file and view some rules that Laravel must follow during the initialization period of your application, in our case we will focus on the withExceptions method, which allows us execute some code when an exception is thrown.

->withExceptions(function (Exceptions $exceptions) {
    //
})
Enter fullscreen mode Exit fullscreen mode

As you can see, the withExceptions method receives as a parameter a class called Exceptions, this class provides a series of methods that help you deal with exceptions thrown in your application. In this article, we will only look at the methods that you will probably use in your day-to-day life, but you can see all the methods in the documentation

Before we see the usefulness of some methods, we need to understand the process (in a simplified way) of how exception throwing works within Laravel:

A simple example of laravel exceptiuns flow

In the example above we can see that, before an exception is returned to the request response, Laravel saves a LOG of the exception regardless of whether you have a registered handler or not, and this behavior can be changed according to the needs of your application. This allows you to prevent Laravel from saving logs automatically and you can choose exactly which log you want to save and in which log channel to save it, making your application more standardized and modularized according to your needs. When an exception is triggered, the log is saved in the file storage/logs/laravel.log

 

Creating Handler

To create your own handler, you can use the report method of the Exceptions class mentioned above. In this method, you pass a callable (an anonymous function or any other function that can be called) passing the exception you want to handle as a parameter. Example:

//inside withExceptions method

$exceptions->report(function (ExampleException $exception) {
    //handle ExampleException
});
Enter fullscreen mode Exit fullscreen mode

In the example above, the callable parameter that we pass to the report method, we receive as a parameter the exception that we want to handle, within this callable we can do whatever we want with the exception, such as returning a standard response, in this way, every time the exception is triggered anywhere in the code (if it is not inside a try catch block), Laravel will execute the callable that we reported for the exception.

$exceptions->report(function (ExampleException $exception) {

    // default response for all ExampleException triggers
    return response()->json([
        'error' => true,
        'message' => 'An error occurred.',
    ], 500);
});
Enter fullscreen mode Exit fullscreen mode

If you want to catch any exception regardless of the class, you can use the Throwable interface introduced in PHP 7:

$exceptions->report(function (Throwable $exception) {

    // default response for any exception
    return response()->json([
        'error' => true,
        'message' => 'Internal Server Error.',
    ], 500);
});
Enter fullscreen mode Exit fullscreen mode

 

Saving Logs

If you want to stop laravel from automatically saving logs after throwing an exception and save your own logs you can stop the handling flow and go to the response through the stop() method.

$exceptions->report(function (Throwable $exception) {
    // Saving Logs
    Log::error("error: {$exception->getMessage()}", [
        'exception' => $exception->getTraceAsString()
    ]);

    // default response for any exception
    return response()->json([
        'error' => true,
        'message' => 'Internal Server Error.',
    ], 500);
})->stop();
Enter fullscreen mode Exit fullscreen mode

It is also possible to stop the handling flow by returning false in the report callable.

$exceptions->report(function (Throwable $exception) {
    // Saving Logs
    Log::error("error: {$exception->getMessage()}", [
        'exception' => $exception->getTraceAsString()
    ]);

    return false;
});
Enter fullscreen mode Exit fullscreen mode

In this way, laravel does not execute the "CREATE LARAVEL LOGS" process mentioned previously in the error handling flow image

 

There are some other methods in the Exceptions class that can be used in your day to day life. Below you can see a table with the names of the methods and a description of their usefulness in use.

 

Class: Exceptions

Method Utility
dontReport receives an array with all the classes that you don't want to report to log channels
stopIgnoring receives an array with all the classes that you want to stop ignoring by default, like http exceptions
render receives a callable that uses two parameters, the first being the exception you want to handle and the second parameter being the request received, through this method it is possible to render a frontend page

 

Tip: It is possible to change the default laravel error pages by publishing them from the vendor

php artisan vendor:publish --tag=laravel-errors
Enter fullscreen mode Exit fullscreen mode

 

Remember that this article is just a simplified demonstration and with a slightly more informal language so that it can reach as many people as possible, you can view in-depth details of each implementation through the Official Laravel Documentation

Top comments (0)