Files

114 lines
4.3 KiB
PHP

<?php
use App\Models\Error;
use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Foundation\Configuration\Middleware;
use Illuminate\Http\Exceptions\HttpResponseException;
use Illuminate\Http\Exceptions\ThrottleRequestsException;
use Illuminate\Http\Request;
use Illuminate\Session\TokenMismatchException;
use Illuminate\Validation\ValidationException;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
return Application::configure(basePath: dirname(__DIR__))
->withRouting(
web: __DIR__.'/../routes/web.php',
commands: __DIR__.'/../routes/console.php',
health: '/up',
)
->withMiddleware(function (Middleware $middleware): void {
$middleware->append(\App\Http\Middleware\SecurityHeaders::class);
})
->withExceptions(function (Exceptions $exceptions): void {
$exceptions->report(function (Throwable $exception): void {
if ($exception instanceof ThrottleRequestsException
|| $exception instanceof ValidationException
|| $exception instanceof HttpResponseException) {
return;
}
if ($exception instanceof HttpExceptionInterface
&& in_array($exception->getStatusCode(), [401, 403, 404, 419, 422, 429], true)) {
return;
}
try {
$codigo = (string) $exception->getCode();
if ($codigo === '') {
$codigo = class_basename($exception);
}
$url = app()->runningInConsole()
? 'console'
: (string) request()?->fullUrl();
Error::query()->create([
'codigo' => mb_substr($codigo, 0, 255),
'mensaje' => mb_substr((string) ($exception->getMessage() ?: class_basename($exception)), 0, 65000),
'track_trace' => mb_substr($exception->getTraceAsString(), 0, 65000),
'url' => mb_substr($url !== '' ? $url : 'desconocida', 0, 255),
'fecha_hora' => now(),
]);
} catch (Throwable $loggingException) {
// Evita que un error al registrar el error rompa el flujo original.
}
});
$exceptions->render(function (ThrottleRequestsException $exception, Request $request) {
$retryAfter = (int) ($exception->getHeaders()['Retry-After'] ?? 60);
$retryAfter = max($retryAfter, 1);
$minutos = intdiv($retryAfter, 60);
$segundos = $retryAfter % 60;
$partesTiempo = [];
if ($minutos > 0) {
$partesTiempo[] = $minutos . ' minuto' . ($minutos === 1 ? '' : 's');
}
if ($segundos > 0 || empty($partesTiempo)) {
$partesTiempo[] = $segundos . ' segundo' . ($segundos === 1 ? '' : 's');
}
$mensaje = 'Demasiados intentos. Esperá ' . implode(' y ', $partesTiempo) . ' antes de volver a intentar.';
if ($request->expectsJson()) {
return response()->json([
'message' => $mensaje,
'retry_after' => $retryAfter,
], 429, $exception->getHeaders());
}
$sessionKey = $request->is('login/*') ? 'login_error' : 'recuperar_error';
return back()
->withInput($request->except([
'contra',
'contra_confirmation',
'contra_actual',
'contra_actual_secreta',
]))
->with($sessionKey, $mensaje);
});
$exceptions->render(function (TokenMismatchException $exception, Request $request) {
$mensaje = 'La sesión cambió en otra pestaña o expiró. Recargá la página y volvé a intentar.';
if ($request->expectsJson()) {
return response()->json([
'message' => $mensaje,
], 419);
}
return back()
->withInput($request->except([
'contra',
'contra_confirmation',
'contra_actual',
'contra_actual_secreta',
]))
->withErrors(['csrf' => $mensaje]);
});
})->create();