Advertisement
  1. Code
  2. Laravel

Manejo de Excepciones en Laravel

Scroll to top
Read Time: 8 min

() translation by (you can also view the original English article)

En este artículo, vamos a explorar una de las características más importantes y menos discutidas del marco de trabajo web Laravel---manejo de excepciones. Laravel viene con un manejador de excepciones integrado que te permite reportar y generar excepciones de manera sencilla y amigable.

En la primera mitad del artículo, vamos a explorar los ajustes por defecto proporcionados por el manejador de excepciones. De hecho, recorreremos la clase Handler por defecto en primer lugar para entender cómo maneja excepciones Laravel.

En la segunda mitad del artículo, vamos a continuar y ver cómo podrías crear un manejador de excepciones personalizado que te permita atrapar excepciones personalizadas.

Configurando los Pre-requisitos

Antes de continuar y sumergirnos en la clase Handler, echemos un vistazo a un par de importantes parámetros de configuración relacionados con excepciones.

Continua y abre el archivo config/app.php. Echemos un vistazo de cerca al siguiente código.

1
...
2
...
3
/*

4
|--------------------------------------------------------------------------

5
| Application Debug Mode

6
|--------------------------------------------------------------------------

7
|

8
| When your application is in debug mode, detailed error messages with

9
| stack traces will be shown on every error that occurs within your

10
| application. If disabled, a simple generic error page is shown.

11
|

12
*/
13
14
'debug' => env('APP_DEBUG', false),
15
...
16
...

Como el nombre sugiere, si se establece a TRUE, te ayudará a depurar errores que son generados por una aplicación. El valor por defecto de esta variable está establecido al valor de la variable de entorno APP_DEBUG en el archivo .env.

En el entorno de desarrollo, deberías establecerla a TRUE para que puedas detectar fácilmente errores y repararlos. Por otro lado, querrás apagarlo en el entorno de producción, y mostrará una página genérica de error en ese caso.

En adición a mostrar errores, Laravel te permite registrar errores en el archivo de registro. Echemos un vistazo rápido a las opciones disponibles para registrar. De nuevo, cambienmos al archivo config/app.php y echemos un vistazo cercano al siguiente código.

1
...
2
...
3
'log' => env('APP_LOG', 'single'),
4
5
'log_level' => env('APP_LOG_LEVEL', 'debug'),
6
...
7
...

Ya que Laravel usa la librería Monolog PHP para registrar, deberías establecer las opciones de arriba en el contexto de esa librería.

El archivo de registro por defecto está ubicado en storage/logs/laravel.log, y es suficiente en la mayoría de los casos. Por otro lado, el APP_LOG_LEVEL está establecido a un valor que indica la severidad de los errores que serán registrados.

Así que esa es la introducción básica a las opciones de configuración disponibles para excepciones y registro.

A continuación, echemos un vistazo a la clase Handler por defecto que viene con la aplicación por defecto de Laravel. Continua y abre el archivo app/Exceptions/Handler.php.

1
<?php
2
3
namespace App\Exceptions;
4
5
use Exception;
6
use Illuminate\Auth\AuthenticationException;
7
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
8
9
class Handler extends ExceptionHandler
10
{
11
    /**

12
     * A list of the exception types that should not be reported.

13
     *

14
     * @var array

15
     */
16
    protected $dontReport = [
17
        \Illuminate\Auth\AuthenticationException::class,
18
        \Illuminate\Auth\Access\AuthorizationException::class,
19
        \Symfony\Component\HttpKernel\Exception\HttpException::class,
20
        \Illuminate\Database\Eloquent\ModelNotFoundException::class,
21
        \Illuminate\Session\TokenMismatchException::class,
22
        \Illuminate\Validation\ValidationException::class,
23
    ];
24
25
    /**

26
     * Report or log an exception.

27
     *

28
     * This is a great spot to send exceptions to Sentry, Bugsnag, etc.

29
     *

30
     * @param  \Exception  $exception

31
     * @return void

32
     */
33
    public function report(Exception $exception)
34
    {
35
        parent::report($exception);
36
    }
37
38
    /**

39
     * Render an exception into an HTTP response.

40
     *

41
     * @param  \Illuminate\Http\Request  $request

42
     * @param  \Exception  $exception

43
     * @return \Illuminate\Http\Response

44
     */
45
    public function render($request, Exception $exception)
46
    {
47
        return parent::render($request, $exception);
48
    }
49
50
    /**

51
     * Convert an authentication exception into an unauthenticated response.

52
     *

53
     * @param  \Illuminate\Http\Request  $request

54
     * @param  \Illuminate\Auth\AuthenticationException  $exception

55
     * @return \Illuminate\Http\Response

56
     */
57
    protected function unauthenticated($request, AuthenticationException $exception)
58
    {
59
        if ($request->expectsJson()) {
60
            return response()->json(['error' => 'Unauthenticated.'], 401);
61
        }
62
63
        return redirect()->guest(route('login'));
64
    }
65
}

Hay dos funciones importantes por las que es responsable la clase handler---repoerar y generar todos los errores.

Echemos un vistazo al método report.

1
/**

2
 * Report or log an exception.

3
 *

4
 * This is a great spot to send exceptions to Sentry, Bugsnag, etc.

5
 *

6
 * @param  \Exception  $exception

7
 * @return void

8
 */
9
public function report(Exception $exception)
10
{
11
    parent::report($exception);
12
}

El método report es usado para registrar errores al archivo de bitácora. Al mismo tiempo, también es importante notar la propiedad dontReport, la cual lista todos los tipos de excepciones que no deberían ser registradas.

A continuación, traigamos el método render.

1
/**

2
 * Render an exception into an HTTP response.

3
 *

4
 * @param  \Illuminate\Http\Request  $request

5
 * @param  \Exception  $exception

6
 * @return \Illuminate\Http\Response

7
 */
8
public function render($request, Exception $exception)
9
{
10
    return parent::render($request, $exception);
11
}

Si el método report es usado para registrar o reportar errores, el método render es usado para generar errores en una pantalla. De hecho, este método maneja lo que será mostrado a los usuarios cuando ocurre una excepción.

El método render también te permite personalizar una respuesta para diferentes tipos de excepciones, como veremos en la siguiente sección.

Finalmente, el método unauthenticated maneja la excepción AuthenticationException que te permite decidir lo que será mostrado a los usuarios en caso de que no estén autenticados para acceder a la página que están buscando.

Clase de Excepción Personalizada

En esta sección, crearemos una clase de excepción personalizada que maneje excepciones del tipo CustomException. La idea detrás de crear clases de excepción personalizada es administrar fácilmente excepciones personalizadas y generar respuesta personalizadas al mismo tiempo.

Continua y crea un archivo app/Exceptions/CustomException.php con el siguiente contenido.

1
<?php
2
3
namespace App\Exceptions;
4
5
use Exception;
6
7
class CustomException extends Exception
8
{
9
    /**

10
     * Report the exception.

11
     *

12
     * @return void

13
     */
14
    public function report()
15
    {
16
    }
17
18
    /**

19
     * Render the exception into an HTTP response.

20
     *

21
     * @param  \Illuminate\Http\Request

22
     * @return \Illuminate\Http\Response

23
     */
24
    public function render($request)
25
    {
26
        return response()->view(
27
                'errors.custom',
28
                array(
29
                    'exception' => $this
30
                )
31
        );
32
    }
33
}

Lo importante a notar aquí es que la clase CustomException debe extender a la clase principal Exception. Para propósitos de la demostración, solo discutiremos el método render, pero claro que podrías también personalizar el método report.

Como puedes ver, estamos redirigiendo a los usuarios a la página de error errors.custom en nuestro caso. De esa manera, puedes implementar páginas de error personalizadas para tipos específicos de excepciones.

Por supuesto, necesitamos crear un archivo de vista asociado en resources/views/errors/custom.blade.php.

1
Exception details: <b>{{ $exception->getMessage() }}</b>

Ese es un archivo de vista muy simple que muestra un mensaje de error, pero por supuesto podrías diseñarlo de la manera que quieres que sea.

También necesitamos hacer cambios en el método de generación del archivo app/Exceptions/Handler.php para que nuestra clase personalizada de excepción pueda ser invocada. Reemplacemos el método render con los siguientes contenidos en el archivo app/Exceptions/Handler.php.

1
...
2
...
3
/**

4
 * Render an exception into an HTTP response.

5
 *

6
 * @param  \Illuminate\Http\Request  $request

7
 * @param  \Exception  $exception

8
 * @return \Illuminate\Http\Response

9
 */
10
public function render($request, Exception $exception)
11
{
12
    if ($exception instanceof \App\Exceptions\CustomException)  {
13
        return $exception->render($request);
14
    }
15
16
    return parent::render($request, $exception);
17
}
18
...
19
...

Como puedes ver, estamos revisando el tipo de una excepción en el método de generación en primer lugar. Si el tipo de una excepción es \App\Exceptions\CustomException, llamamos al método de generación de esa clase.

Así que todo está en su lugar ahora. Después, continua y crea un archivo controlador en app/Http/Controllers/ExceptionController.php para que podamos probar nuestra clase personalizada de excepción.

1
<?php
2
namespace App\Http\Controllers;
3
4
use App\Http\Controllers\Controller;
5
6
class ExceptionController extends Controller
7
{
8
    public function index()
9
    {
10
        // something went wrong and you want to throw CustomException

11
        throw new \App\Exceptions\CustomException('Something Went Wrong.');
12
    }
13
}

Por supuesto, necesitas crear una ruta asociada en routes/web.php como se muestra en el siguiente código.

1
// Exception routes

2
Route::get('exception/index', 'ExceptionController@index');

Y con eso en su lugar, puedes ejecutar la URL http://your-laravel-site.com/exception/index para ver si funciona como se espera. Debería mostrar la vista errors.custom como nuestra configuración.

Así es como se supone que manejes excepciones personalizadas en Laravel. Y eso nos lleva al final de este artículo---¡espero que lo hayas disfrutado!

Conclusión

Hoy, recorrimos la característica de manejo de excepción en Laravel. Al inicio del artículo, exploramos la configuración básica provista por Laravel para generar y reportar excepciones. Más adelante, echamos un vistazo breve a la clase manejadora de excepción por defecto.

En la segunda mitad del artículo, preparamos una clase de excepción personalizada que te demostró como podrías manejar excepciones personalizadas en tu aplicación.

Para aquellos de ustedes que están comenzando con Laravel o están buscando expandir su conocimiento, sitio o aplicación con extensiones, tenemos una variedad de cosas que puedes estudiar en Envato Market.

¡Me encantaría escuchar de ti en forma de preguntas y sugerencias!

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.