Remove auto-recovery mechanism that caused race conditions with view cache

This commit is contained in:
root
2026-05-26 16:05:58 +02:00
parent 4aa574e75e
commit 45848cb4c5
-68
View File
@@ -9,7 +9,6 @@ use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Auth\AuthenticationException; use Illuminate\Auth\AuthenticationException;
use Illuminate\Database\QueryException; use Illuminate\Database\QueryException;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler; use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use Illuminate\Validation\ValidationException; use Illuminate\Validation\ValidationException;
@@ -38,85 +37,18 @@ class Handler extends ExceptionHandler
private const int ERROR_COUNT_DURATION = 300; private const int ERROR_COUNT_DURATION = 300;
private const array AUTO_RECOVERABLE_ERRORS = [
'ViteManifestNotFoundException',
'filemtime',
'stat failed for',
'No application encryption key has been specified',
'file does not exist',
'view [',
'Target class [view] does not exist',
'BindingResolutionException',
];
private const int AUTO_RECOVER_COOLDOWN = 60;
#[\Override] #[\Override]
public function register(): void public function register(): void
{ {
$this->reportable(function (Throwable $e) { $this->reportable(function (Throwable $e) {
$this->attemptAutoRecovery($e);
$this->handleExceptionAlert($e); $this->handleExceptionAlert($e);
}); });
$this->renderable(function (Throwable $e) { $this->renderable(function (Throwable $e) {
$recovered = $this->attemptAutoRecovery($e);
if ($recovered) {
return redirect()->to(request()->url());
}
$this->handleExceptionAlert($e); $this->handleExceptionAlert($e);
}); });
} }
private function attemptAutoRecovery(Throwable $e): bool
{
$message = $e->getMessage() ?: '';
$exceptionClass = $e::class;
$isRecoverable = array_any(self::AUTO_RECOVERABLE_ERRORS, fn ($pattern) => str_contains($exceptionClass, (string) $pattern) || str_contains($message, (string) $pattern));
if (! $isRecoverable) {
return false;
}
$cacheKey = 'auto_recovery_cooldown';
if (Cache::has($cacheKey)) {
return false;
}
Cache::put($cacheKey, true, self::AUTO_RECOVER_COOLDOWN);
Log::warning('Attempting auto-recovery from error', [
'exception' => $exceptionClass,
'message' => $message,
]);
try {
Artisan::call('view:clear');
Artisan::call('cache:clear');
Artisan::call('config:clear');
Artisan::call('route:clear');
Artisan::call('config:cache');
Artisan::call('view:cache');
if (function_exists('opcache_reset')) {
@opcache_reset();
}
Log::info('Auto-recovery completed successfully');
return true;
} catch (Throwable $recoveryError) {
Log::error('Auto-recovery failed', [
'original_error' => $message,
'recovery_error' => $recoveryError->getMessage(),
]);
return false;
}
}
private function handleExceptionAlert(Throwable $e): void private function handleExceptionAlert(Throwable $e): void
{ {
if (! $this->shouldAlertException($e)) { if (! $this->shouldAlertException($e)) {