mirror of
https://github.com/coollabsio/coolify.git
synced 2026-11-06 13:10:37 -04:00
fix(sentinel): surface remote fetch errors instead of a TypeError
Let instant_remote_process throw on failed SSH/docker commands so the real error (e.g. a missing coolify-sentinel container or an unreadable SSH key) is reported. A null result, such as a literal "null" body, is turned into an empty string, which guard() rejects as an invalid response. Run curl with -sS so progress output stays out of the output while errors are still reported. Add tests for a failed docker exec and a literal null body.
This commit is contained in:
@@ -729,11 +729,9 @@ class SentinelTrafficClient
|
||||
{
|
||||
$token = $this->server->settings->ensureValidSentinelToken();
|
||||
|
||||
return instant_remote_process(
|
||||
[$this->buildFetchCommand($token, $url)],
|
||||
$this->server,
|
||||
false
|
||||
);
|
||||
// Throw the real SSH/docker error (for example, an unreadable SSH key or a missing
|
||||
// container). A literal "null" body comes back as null; guard() rejects the empty string.
|
||||
return instant_remote_process([$this->buildFetchCommand($token, $url)], $this->server) ?? '';
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -743,11 +741,7 @@ class SentinelTrafficClient
|
||||
{
|
||||
$token = $this->server->settings->ensureValidSentinelToken();
|
||||
|
||||
return instant_remote_process(
|
||||
[$this->buildBatchCommand($token, $urls)],
|
||||
$this->server,
|
||||
false
|
||||
);
|
||||
return instant_remote_process([$this->buildBatchCommand($token, $urls)], $this->server) ?? '';
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -762,7 +756,7 @@ class SentinelTrafficClient
|
||||
*/
|
||||
protected function buildFetchCommand(string $token, string $url): string
|
||||
{
|
||||
return "docker exec coolify-sentinel sh -c 'curl -H \"Authorization: Bearer {$token}\" \"{$url}\"'";
|
||||
return "docker exec coolify-sentinel sh -c 'curl -sS -H \"Authorization: Bearer {$token}\" \"{$url}\"'";
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
<?php
|
||||
|
||||
use App\Models\PrivateKey;
|
||||
use App\Models\Server;
|
||||
use App\Models\Team;
|
||||
use App\Services\SentinelTrafficClient;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\Process;
|
||||
|
||||
uses(RefreshDatabase::class);
|
||||
|
||||
@@ -29,3 +31,20 @@ it('caches identical requests within the TTL', function () {
|
||||
$client->overview('app', 'a', 'b');
|
||||
expect($client->calls)->toBe(1);
|
||||
});
|
||||
|
||||
it('surfaces the real remote error instead of a TypeError when the fetch fails', function (int $exitCode, string $output, string $errorOutput, string $message) {
|
||||
Cache::flush();
|
||||
config()->set('constants.ssh.max_retries', 1);
|
||||
Process::fake(fn () => Process::result(output: $output, errorOutput: $errorOutput, exitCode: $exitCode));
|
||||
$team = Team::factory()->create();
|
||||
$server = Server::factory()->create([
|
||||
'team_id' => $team->id,
|
||||
'private_key_id' => PrivateKey::factory()->create(['team_id' => $team->id])->id,
|
||||
]);
|
||||
|
||||
expect(fn () => (new SentinelTrafficClient($server))->overview('app', 'a', 'b'))
|
||||
->toThrow(RuntimeException::class, $message);
|
||||
})->with([
|
||||
'failed docker exec' => [1, '', 'Error response from daemon: No such container: coolify-sentinel', 'No such container: coolify-sentinel'],
|
||||
'literal null body' => [0, 'null', '', 'Traffic analytics returned an invalid response.'],
|
||||
]);
|
||||
|
||||
Reference in New Issue
Block a user