Introducción
Cuando comienzas un nuevo proyecto de Laravel, el manejo de excepciones y errores ya está configurado para ti. La clase App\Exceptions\Handler
es donde todas las excepciones disparadas por tu aplicación son registradas y después renderizadas de vuelta al usuario. Revisaremos más profundamente dentro de esta clase a través de esta documentación.
Configuración
La opción debug
en tu archivo de configuración config/app.php
determina cuanta información sobre un error se muestra realmente al usuario. Por defecto, esta opción es establecida para respetar el valor de la variable de entorno APP_DEBUG
, la cual es almacenada en tu archivo .env
.
Para desarrollo local, deberías establecer la variable de entorno APP_DEBUG
a true
. En tu entorno de producción, este valor debería estar siempre false
. Si el valor es establecido a true
en producción, te arriesgas a exponer valores de configuración sensibles a los usuarios finales de tu aplicación.
Manejador de excepciones
Método report
Todas las excepciones son manejadas por la clase App\Exceptions\Handler
. Esta clase contiene dos métodos: report
y render
. Examinaremos cada uno de estos métodos en detalle. El método report
se usa para registrar excepciones o enviarlas a un servicio externo como Flare, Bugsnag o Sentry. De forma predeterminada, el método report
pasa la excepción a la clase base donde la excepción es registrada. Sin embargo, eres libre de registrar excepciones en la forma que desees.
Por ejemplo, si necesitas reportar distintos tipos de excepciones en diferentes formas, puedes usar el operador de comparación instanceof
de PHP:
/** * Report or log an exception. * * This is a great spot to send exceptions to Flare, Sentry, Bugsnag, etc. * * @param \Exception $exception * @return void */ public function report(Exception $exception) { if ($exception instanceof CustomException) { // } parent::report($exception); }
En lugar de hacer uso de muchos instanceof
en tu método report
, considera usar excepciones reportables
Contexto de log global
De estar disponible, Laravel automáticamente agrega el ID del usuario actual al mensaje de log de cada excepción como datos contextuales. Puedes definir tus propios datos contextuales globales sobrescribiendo el método context
de la clase App\Exceptions\Handler
de tu aplicación. Esta información será incluida en cada mensaje de log de excepción escrito por tu aplicación:
/** * Get the default context variables for logging. * * @return array */ protected function context() { return array_merge(parent::context(), [ 'foo' => 'bar', ]); }
Helper report
Algunas veces puede que necesites reportar una excepción, pero continuar manejando la solicitud actual. La función helper report
permite que reportes rápidamente una excepción usando el método report
de tu manejador de excepciones sin renderizar una página de error:
public function isValid($value) { try { // Validate the value... } catch (Exception $e) { report($e); return false; } }
Ignorando excepciones por tipo
La propiedad $dontReport
del manejador de excepción contiene un arreglo de tipos de excepción que no serán registrados. Por ejemplo, excepciones que resulten de errores 404, al igual que otros varios tipos de errores, no son escritos a tus archivos de log. Puedes agregar otros tipos de excepción a este arreglo cuando lo necesites:
/** * A list of the exception types that should not be reported. * * @var array */ protected $dontReport = [ \Illuminate\Auth\AuthenticationException::class, \Illuminate\Auth\Access\AuthorizationException::class, \Symfony\Component\HttpKernel\Exception\HttpException::class, \Illuminate\Database\Eloquent\ModelNotFoundException::class, \Illuminate\Validation\ValidationException::class, ];
Método render
El método render
es responsable de convertir una excepción dada en una respuesta HTTP que debería ser devuelta al navegador. De forma predeterminada, la excepción es pasada a la clase base la cual genera una respuesta para ti. Sin embargo, eres libre de revisar el tipo de excepción o devolver tu propia respuesta personalizada:
/** * Render an exception into an HTTP response. * * @param \Illuminate\Http\Request $request * @param \Exception $exception * @return \Illuminate\Http\Response */ public function render($request, Exception $exception) { if ($exception instanceof CustomException) { return response()->view('errors.custom', [], 500); } return parent::render($request, $exception); }
Excepciones renderizables y reportables
En lugar de hacer verificaciones por tipo de excepciones en los métodos report
y render
del manejador de excepciones, puedes definir métodos report
y render
directamente en tu excepción personalizada. Cuando estos métodos existen, serán ejecutados automáticamente por el framework:
<?php namespace App\Exceptions; use Exception; class RenderException extends Exception { /** * Report the exception. * * @return void */ public function report() { // } /** * Render the exception into an HTTP response. * * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\Response */ public function render($request) { return response(...); } }
Puedes declarar el tipo de cualquier dependencia requerida en el método report
y el contenedor de servicios de Laravel las inyectará automáticamente en el método.
Excepciones HTTP
Algunas excepciones describen códigos de error HTTP del servidor. Por ejemplo, esto puede ser un error «página no encontrada» (404), un «error no autorizado» (401) o incluso un error 500 generado por el desarrollador. Con el propósito de generar tal respuesta desde cualquier lugar en tu aplicación, puedes usar el helper abort
:
abort(404);
El helper abort
provocará inmediatamente una excepción la cual será renderizada por el manejador de excepción. Opcionalmente, puedes proporcionar el texto de la respuesta:
abort(403, 'Unauthorized action.');
Páginas de error HTTP personalizadas
Laravel hace fácil mostrar páginas de error personalizadas para varios códigos de estado HTTP. Por ejemplo, si deseas personalizar la página de error para los códigos de estado HTTP 404, crea una vista resources/views/errors/404.blade.php
. Este archivo será servido en todos los errores 404 generados por tu aplicación. La vista dentro de este directorio debería ser nombrada para coincidir con el código de estado HTTP que les corresponde. La instancia HttpException
provocada por la función abort
será pasada a la vista como una variable $exception
:
<h2>{{ $exception->getMessage() }}</h2>
Puedes publicar las plantillas de página de error de Laravel usando el comando de Artisan vender:publish
. Una vez que las plantillas han sido publicadas, puedes personalizarlas de la forma que quieras:
php artisan vendor:publish --tag=laravel-errors
Regístrate hoy en Styde y obtén acceso a todo nuestro contenido.
Lección anterior Validación - Documentación de Laravel 6 Lección siguiente Registro (Logging) - Documentación de Laravel 6