115 lines
3.5 KiB
PHP
115 lines
3.5 KiB
PHP
<?php
|
|||
|
|
|
||
|
|
namespace App\Traits;
|
||
|
|
|
||
|
|
use App\Models\JobFetchLog;
|
||
|
|
use Illuminate\Support\Facades\Log;
|
||
|
|
|
||
|
|
trait HandlesJobErrors
|
||
|
|
{
|
||
|
|
/**
|
||
|
|
* Handle job fetch errors gracefully
|
||
|
|
*/
|
||
|
|
protected function handleFetchError(
|
||
|
|
int $sourceId,
|
||
|
|
\Exception $exception,
|
||
|
|
array $metadata = []
|
||
|
|
): void {
|
||
|
|
// Log the error
|
||
|
|
Log::error('Job fetch failed', [
|
||
|
|
'source_id' => $sourceId,
|
||
|
|
'error' => $exception->getMessage(),
|
||
|
|
'trace' => $exception->getTraceAsString(),
|
||
|
|
'metadata' => $metadata,
|
||
|
|
]);
|
||
|
|
|
||
|
|
// Record in database
|
||
|
|
JobFetchLog::create([
|
||
|
|
'job_source_id' => $sourceId,
|
||
|
|
'success' => false,
|
||
|
|
'jobs_fetched' => 0,
|
||
|
|
'jobs_created' => 0,
|
||
|
|
'jobs_updated' => 0,
|
||
|
|
'jobs_skipped' => 0,
|
||
|
|
'error_message' => $exception->getMessage(),
|
||
|
|
'metadata' => array_merge($metadata, [
|
||
|
|
'exception_class' => get_class($exception),
|
||
|
|
'file' => $exception->getFile(),
|
||
|
|
'line' => $exception->getLine(),
|
||
|
|
]),
|
||
|
|
]);
|
||
|
|
|
||
|
|
// Check if we need to disable the source due to repeated failures
|
||
|
|
$this->checkAndDisableSource($sourceId);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Check for repeated failures and disable source if necessary
|
||
|
|
*/
|
||
|
|
protected function checkAndDisableSource(int $sourceId): void
|
||
|
|
{
|
||
|
|
$recentFailures = JobFetchLog::where('job_source_id', $sourceId)
|
||
|
|
->where('success', false)
|
||
|
|
->where('created_at', '>=', now()->subHours(24))
|
||
|
|
->count();
|
||
|
|
|
||
|
|
// Disable source after 5 consecutive failures in 24 hours
|
||
|
|
if ($recentFailures >= 5) {
|
||
|
|
$source = \App\Models\JobSource::find($sourceId);
|
||
|
|
if ($source && $source->is_active) {
|
||
|
|
$source->update(['is_active' => false]);
|
||
|
|
|
||
|
|
Log::warning("Source {$source->name} has been disabled due to repeated failures", [
|
||
|
|
'source_id' => $sourceId,
|
||
|
|
'failures' => $recentFailures,
|
||
|
|
]);
|
||
|
|
|
||
|
|
// You could send a notification to admins here
|
||
|
|
$this->notifyAdmins($source, $recentFailures);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Log successful job fetch
|
||
|
|
*/
|
||
|
|
protected function logSuccessfulFetch(
|
||
|
|
int $sourceId,
|
||
|
|
int $jobsFetched,
|
||
|
|
int $jobsCreated,
|
||
|
|
int $jobsUpdated,
|
||
|
|
int $jobsSkipped,
|
||
|
|
int $durationSeconds,
|
||
|
|
array $metadata = []
|
||
|
|
): void {
|
||
|
|
JobFetchLog::create([
|
||
|
|
'job_source_id' => $sourceId,
|
||
|
|
'success' => true,
|
||
|
|
'jobs_fetched' => $jobsFetched,
|
||
|
|
'jobs_created' => $jobsCreated,
|
||
|
|
'jobs_updated' => $jobsUpdated,
|
||
|
|
'jobs_skipped' => $jobsSkipped,
|
||
|
|
'duration_seconds' => $durationSeconds,
|
||
|
|
'metadata' => $metadata,
|
||
|
|
]);
|
||
|
|
|
||
|
|
Log::info('Job fetch completed successfully', [
|
||
|
|
'source_id' => $sourceId,
|
||
|
|
'jobs_fetched' => $jobsFetched,
|
||
|
|
'jobs_created' => $jobsCreated,
|
||
|
|
'jobs_updated' => $jobsUpdated,
|
||
|
|
'duration' => $durationSeconds,
|
||
|
|
]);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Notify admins about source failure (placeholder)
|
||
|
|
*/
|
||
|
|
protected function notifyAdmins($source, int $failureCount): void
|
||
|
|
{
|
||
|
|
// TODO: Implement notification logic
|
||
|
|
// Could use Laravel notifications, email, Slack, etc.
|
||
|
|
Log::critical("ADMIN ALERT: Source {$source->name} disabled after {$failureCount} failures");
|
||
|
|
}
|
||
|
|
}
|