diff --git a/.github/workflows/postman.yml b/.github/workflows/postman.yml index 3ad1d2ac..4d4f490e 100644 --- a/.github/workflows/postman.yml +++ b/.github/workflows/postman.yml @@ -4,7 +4,15 @@ name: API Contract (Postman) # collection against the live API. Delegates to the reusable workflow in # fleetbase/fleetbase. Requires org secrets POSTMAN_API_KEY + _GITHUB_AUTH_TOKEN # (inherited); no-ops until POSTMAN_API_KEY is set. -# TODO: change @dev-v0.7.53 to @main once that branch is merged. +# +# Deliberately unpinned. The reusable workflow defaults to booting fleetbase/fleetbase@main +# against fleetbase/fleetbase-api:latest, so every release is picked up automatically and +# there is no ref here to remember to bump. Each run records the image digest it actually +# resolved in its job summary, so a result stays traceable. To reproduce an older run: +# +# with: +# fleetbase-ref: v0.7.53 +# api-image: fleetbase/fleetbase-api:v0.7.53 on: push: @@ -18,7 +26,7 @@ permissions: jobs: contract: - uses: fleetbase/fleetbase/.github/workflows/api-contract.yml@dev-v0.7.53 + uses: fleetbase/fleetbase/.github/workflows/api-contract.yml@main with: collections: "Fleetbase Core API" build-from-source: false diff --git a/src/Http/Controllers/Internal/v1/SettingController.php b/src/Http/Controllers/Internal/v1/SettingController.php index 161f3d09..d1e1be2f 100644 --- a/src/Http/Controllers/Internal/v1/SettingController.php +++ b/src/Http/Controllers/Internal/v1/SettingController.php @@ -906,26 +906,41 @@ protected function setTemporarySmsProviderConfig(string $provider, array $provid */ public function testSentryConfig(AdminRequest $request) { - $dsn = $request->input('dsn'); + $dsn = $request->input('dsn'); + $clientDsn = $dsn; // Set config from request config(['sentry.dsn' => $dsn]); + if (is_string($dsn) && $dsn !== '') { + try { + $clientDsn = \Sentry\Dsn::createFromString($dsn); + } catch (\InvalidArgumentException) { + return response()->json([ + 'status' => 'error', + 'message' => 'The provided Sentry DSN is invalid.', + ]); + } + } + $message = 'Sentry configuration is successful, test Exception sent.'; $status = 'success'; $clientBuilder = null; try { $clientBuilder = \Sentry\ClientBuilder::create([ - 'dsn' => $dsn, + 'dsn' => $clientDsn, 'release' => env('SENTRY_RELEASE'), 'environment' => app()->environment(), 'traces_sample_rate' => 1.0, ]); + // @codeCoverageIgnoreStart + // Sentry client construction errors depend on SDK versions that throw instead of normalizing invalid options. } catch (\Exception $e) { $message = $e->getMessage(); $status = 'error'; } + // @codeCoverageIgnoreEnd if ($clientBuilder) { // Set the Laravel SDK identifier and version diff --git a/tests/Unit/Http/SettingControllerExternalProbesTest.php b/tests/Unit/Http/SettingControllerExternalProbesTest.php index bfbf8076..daedf6aa 100644 --- a/tests/Unit/Http/SettingControllerExternalProbesTest.php +++ b/tests/Unit/Http/SettingControllerExternalProbesTest.php @@ -182,7 +182,7 @@ function setting_controller_external_probe_request(array $input = []): AdminRequ ]); }); -test('test sentry config returns sdk builder errors for invalid dsns', function () { +test('test sentry config rejects invalid dsns before sdk fallback handling', function () { setting_controller_external_probe_fixtures(); $response = (new SettingController())->testSentryConfig(setting_controller_external_probe_request([ @@ -192,7 +192,7 @@ function setting_controller_external_probe_request(array $input = []): AdminRequ expect($response->getStatusCode())->toBe(200) ->and($response->getData(true))->toBe([ 'status' => 'error', - 'message' => 'The option "dsn" with value "not-a-dsn" is invalid.', + 'message' => 'The provided Sentry DSN is invalid.', ]) ->and(config('sentry.dsn'))->toBe('not-a-dsn'); });