Error Handling

Avanzado
Laravel
Laravel
Actualizado: 24/09/2025

Gestión de errores

Laravel proporciona un sistema robusto para el manejo de excepciones que funciona de manera automática desde el momento en que creates tu proyecto. Sin embargo, la verdadera ventaja radica en la capacidad de personalizar cómo tu aplicación reporta y renderiza las excepciones según las necesidades específicas de tu proyecto.

Configuración básica del manejo de errores

El punto central para configurar el manejo de excepciones en Laravel se encuentra en el archivo bootstrap/app.php, donde puedes utilizar el método withExceptions() para personalizar el comportamiento:

<?php

use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;

return Application::configure(basePath: dirname(__DIR__))
    ->withRouting(
        web: __DIR__.'/../routes/web.php',
        commands: __DIR__.'/../routes/console.php',
        health: '/up',
    )
    ->withExceptions(function (Exceptions $exceptions) {
        // Configuración personalizada de excepciones
    })
    ->create();

La variable de entorno APP_DEBUG en tu archivo .env controla cuánta información sobre errores se muestra al usuario. Durante el desarrollo local debes mantenerla como true, pero en producción siempre debe ser false para evitar exponer información sensible.

Reporteo personalizado de excepciones

El reporteo de excepciones te permite registrar errores en logs o enviarlos a servicios externos como Sentry. Puedes configurar diferentes comportamientos según el tipo de excepción:

use App\Exceptions\PaymentException;
use App\Exceptions\OrderException;

->withExceptions(function (Exceptions $exceptions) {
    // Reportar excepciones de pago a un servicio específico
    $exceptions->report(function (PaymentException $e) {
        // Enviar a servicio de monitoreo de pagos
        logger()->critical('Payment error occurred', [
            'user_id' => auth()->id(),
            'amount' => $e->getAmount(),
            'error' => $e->getMessage()
        ]);
    });

    // Reportar errores de pedidos con contexto adicional
    $exceptions->report(function (OrderException $e) {
        // Notificar al equipo de soporte
        return true; // Continúa con el log normal
    });
})

Control de contexto en logs

Laravel automáticamente añade el ID del usuario actual a los logs de excepciones. Puedes agregar contexto global adicional que aparecerá en todos los logs de errores:

->withExceptions(function (Exceptions $exceptions) {
    $exceptions->context(function () {
        return [
            'environment' => app()->environment(),
            'version' => config('app.version'),
            'request_id' => request()->header('X-Request-ID'),
        ];
    });
})

Para excepciones específicas, puedes definir contexto particular implementando el método context() en tu clase de excepción:

<?php

namespace App\Exceptions;

use Exception;

class ApiException extends Exception
{
    public function __construct(
        string $message,
        private string $endpoint,
        private array $requestData = []
    ) {
        parent::__construct($message);
    }

    public function context(): array
    {
        return [
            'api_endpoint' => $this->endpoint,
            'request_data' => $this->requestData,
            'timestamp' => now()->toISOString(),
        ];
    }
}

Niveles de log y filtrado de excepciones

Puedes configurar niveles específicos para diferentes tipos de excepciones, lo que afecta cómo se registran en los logs:

use PDOException;
use Psr\Log\LogLevel;

->withExceptions(function (Exceptions $exceptions) {
    // Errores de base de datos como críticos
    $exceptions->level(PDOException::class, LogLevel::CRITICAL);
    
    // Ignorar ciertos tipos de excepciones
    $exceptions->dontReport([
        \App\Exceptions\ValidationException::class,
        \Symfony\Component\HttpKernel\Exception\NotFoundHttpException::class,
    ]);
})

También puedes ignorar excepciones condicionalmente usando el método dontReportWhen():

use App\Exceptions\ThirdPartyException;

->withExceptions(function (Exceptions $exceptions) {
    $exceptions->dontReportWhen(function (Throwable $e) {
        return $e instanceof ThirdPartyException && 
               $e->getCode() === 503 && 
               app()->environment('testing');
    });
})

Renderizado personalizado de excepciones

El renderizado controla cómo se presentan las excepciones al usuario final. Puedes personalizar las respuestas según el tipo de excepción y el contexto de la petición:

use App\Exceptions\ApiException;
use Illuminate\Http\Request;

->withExceptions(function (Exceptions $exceptions) {
    $exceptions->render(function (ApiException $e, Request $request) {
        if ($request->is('api/*')) {
            return response()->json([
                'error' => [
                    'message' => $e->getMessage(),
                    'code' => $e->getCode(),
                    'timestamp' => now()->toISOString()
                ]
            ], 400);
        }
        
        return response()->view('errors.api-error', [
            'exception' => $e
        ], 400);
    });
})

Función auxiliar report()

La función report() te permite reportar excepciones sin interrumpir el flujo normal de la aplicación. Es especialmente útil para registrar errores recuperables:

public function processPayment($paymentData)
{
    try {
        $result = $this->paymentGateway->charge($paymentData);
        return $result;
    } catch (GatewayTimeoutException $e) {
        // Reportar el error pero intentar método alternativo
        report($e);
        
        return $this->fallbackPaymentMethod($paymentData);
    } catch (PaymentDeclinedException $e) {
        // Reportar y relanzar para manejo específico
        report($e);
        throw $e;
    }
}

Deduplicación de excepciones

Para evitar duplicados en los logs cuando la misma instancia de excepción se reporta múltiples veces, puedes activar la deduplicación:

->withExceptions(function (Exceptions $exceptions) {
    $exceptions->dontReportDuplicates();
})

Throttling de excepciones

En aplicaciones con alto volumen, puedes limitar el número de excepciones reportadas para evitar spam en los logs:

use Illuminate\Support\Lottery;
use Illuminate\Cache\RateLimiting\Limit;

->withExceptions(function (Exceptions $exceptions) {
    $exceptions->throttle(function (Throwable $e) {
        // Solo reportar 1 de cada 100 excepciones de monitoreo
        if ($e instanceof \App\Exceptions\MonitoringException) {
            return Lottery::odds(1, 100);
        }
        
        // Limitar errores de terceros a 50 por minuto
        if ($e instanceof \App\Exceptions\ThirdPartyException) {
            return Limit::perMinute(50)->by($e->getMessage());
        }
        
        return null; // Sin limitación para otros errores
    });
})

Excepciones reportables y renderizables

Puedes crear excepciones inteligentes que manejen su propio reporteo y renderizado implementando los métodos correspondientes directamente en la clase:

<?php

namespace App\Exceptions;

use Exception;
use Illuminate\Http\Request;
use Illuminate\Http\Response;

class BusinessLogicException extends Exception
{
    public function report(): void
    {
        // Solo reportar en producción
        if (app()->environment('production')) {
            logger()->warning($this->getMessage(), [
                'user_id' => auth()->id(),
                'trace' => $this->getTraceAsString()
            ]);
        }
    }

    public function render(Request $request): Response
    {
        if ($request->expectsJson()) {
            return response()->json([
                'message' => 'Business rule violation',
                'details' => $this->getMessage()
            ], 422);
        }

        return response()->view('errors.business-error', [
            'message' => $this->getMessage()
        ], 422);
    }
}

Manejo de excepciones HTTP

Laravel facilita la generación de respuestas HTTP de error usando la función abort():

public function show($id)
{
    $user = User::find($id);
    
    if (!$user) {
        abort(404, 'Usuario no encontrado');
    }
    
    if (!$user->isActive()) {
        abort(403, 'Usuario inactivo');
    }
    
    return view('users.show', compact('user'));
}

Páginas de error personalizadas

Para crear páginas de error personalizadas, simplemente crea vistas en el directorio resources/views/errors/ con el nombre del código de estado HTTP:

resources/views/errors/404.blade.php:

@extends('layouts.app')

@section('title', 'Página no encontrada')

@section('content')
<div class="error-page">
    <h1>¡Ups! Página no encontrada</h1>
    <p>La página que buscas no existe o ha sido movida.</p>
    
    @if(isset($exception))
        <p class="error-message">{{ $exception->getMessage() }}</p>
    @endif
    
    <a href="{{ route('home') }}" class="btn btn-primary">
        Volver al inicio
    </a>
</div>
@endsection

También puedes definir páginas de respaldo para rangos de errores creando archivos como 4xx.blade.php o 5xx.blade.php que se utilizarán cuando no exista una página específica para el código de estado.

Fuentes y referencias

Documentación oficial y recursos externos para profundizar en Laravel

Documentación oficial de Laravel
Alan Sastre - Autor del tutorial

Alan Sastre

Ingeniero de Software y formador, CEO en CertiDevs

Ingeniero de software especializado en Full Stack y en Inteligencia Artificial. Como CEO de CertiDevs, Laravel es una de sus áreas de expertise. Con más de 15 años programando, 6K seguidores en LinkedIn y experiencia como formador, Alan se dedica a crear contenido educativo de calidad para desarrolladores de todos los niveles.

Más tutoriales de Laravel

Explora más contenido relacionado con Laravel y continúa aprendiendo con nuestros tutoriales gratuitos.

Aprendizajes de esta lección

  • Comprender la configuración básica del manejo de excepciones en Laravel.
  • Aprender a personalizar el reporteo y renderizado de excepciones.
  • Configurar niveles de log, contexto y filtrado de errores.
  • Implementar deduplicación y throttling para el control de excepciones.
  • Crear excepciones inteligentes con métodos propios de reporte y renderizado.