fix(jobs): stop notifying on transient CDN failures in version checks

CheckHelperImageJob now logs a warning and returns when the versions
endpoint fails instead of sending an internal notification and
rethrowing. The next scheduled run retries. PullTemplatesFromCDN also
no longer sends internal notifications on non-success responses or
exceptions; it still logs them.

Add tests checking that the stored helper version is kept and that no
notification is sent when the CDN is unavailable.
This commit is contained in:
Andras Bacsai
2026-10-15 15:20:57 +02:00
parent 2c973d68c4
commit 2db26e88ab
4 changed files with 39 additions and 17 deletions
+13 -14
View File
@@ -9,6 +9,7 @@ use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
class CheckHelperImageJob implements ShouldBeEncrypted, ShouldQueue
{
@@ -20,20 +21,18 @@ class CheckHelperImageJob implements ShouldBeEncrypted, ShouldQueue
public function handle(): void
{
try {
$response = Http::retry(3, 1000)->get(config('constants.coolify.versions_url'));
if ($response->successful()) {
$versions = $response->json();
$settings = instanceSettings();
$latest_version = data_get($versions, 'coolify.helper.version');
$current_version = $settings->helper_version;
if (version_compare($latest_version, $current_version, '>')) {
$settings->update(['helper_version' => $latest_version]);
}
}
} catch (\Throwable $e) {
send_internal_notification('CheckHelperImageJob failed with: '.$e->getMessage());
throw $e;
$response = Http::retry(3, 1000, throw: false)->get(config('constants.coolify.versions_url'));
if ($response->failed()) {
// The CDN can be briefly unavailable. The next scheduled run tries again, so do not notify.
Log::warning('CheckHelperImageJob could not fetch versions', ['status' => $response->status()]);
return;
}
$latest_version = data_get($response->json(), 'coolify.helper.version');
$settings = instanceSettings();
if (version_compare($latest_version, $settings->helper_version, '>')) {
$settings->update(['helper_version' => $latest_version]);
}
}
}
-2
View File
@@ -44,13 +44,11 @@ class PullTemplatesFromCDN implements ShouldBeEncrypted, ShouldQueue
'status' => $response->status(),
'body' => str($response->body())->limit(500)->toString(),
]);
send_internal_notification('PullTemplatesAndVersions failed with: '.$response->status().' '.$response->body());
}
} catch (\Throwable $e) {
Log::error('PullTemplatesFromCDN exception', [
'message' => $e->getMessage(),
]);
send_internal_notification('PullTemplatesAndVersions failed with: '.$e->getMessage());
}
}
}
+17
View File
@@ -2,8 +2,10 @@
use App\Jobs\CheckHelperImageJob;
use App\Models\InstanceSettings;
use App\Models\Team;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Notification;
uses(RefreshDatabase::class);
@@ -36,3 +38,18 @@ it('does not use a stored helper version older than the bundled version', functi
expect(getHelperVersion())->toBe('1.0.17');
});
it('keeps the stored helper version and does not notify when the CDN is unavailable', function () {
Team::factory()->create(['id' => 0])->discordNotificationSettings()->update(['discord_enabled' => true]);
InstanceSettings::findOrFail(0)->update(['helper_version' => '1.0.17']);
Notification::fake();
Http::preventStrayRequests();
Http::fake([
'https://cdn.example.com/coolify/versions.json' => Http::response('error code: 1200', 503),
]);
(new CheckHelperImageJob)->handle();
expect(InstanceSettings::findOrFail(0)->helper_version)->toBe('1.0.17');
Notification::assertNothingSent();
});
@@ -1,10 +1,15 @@
<?php
use App\Jobs\PullTemplatesFromCDN;
use App\Models\Team;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Notification;
uses(RefreshDatabase::class);
beforeEach(function () {
Cache::flush();
@@ -146,7 +151,9 @@ it('keeps the local templates when the CDN returns an unusable bundle', function
'json list' => '[1, 2]',
]);
it('logs when the CDN responds with a non-success status', function () {
it('logs without notifying when the CDN responds with a non-success status', function () {
Team::factory()->create(['id' => 0])->discordNotificationSettings()->update(['discord_enabled' => true]);
Notification::fake();
Http::fake([
'cdn.coollabs.io/*' => Http::response('nope', 503),
]);
@@ -160,4 +167,5 @@ it('logs when the CDN responds with a non-success status', function () {
(new PullTemplatesFromCDN)->handle();
expect(Cache::get(service_templates_cache_key()))->toBeNull();
Notification::assertNothingSent();
});