From 9e9ca86a3c89875e0618c7b8be29b584cdbafd0e Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Thu, 30 Apr 2026 11:26:54 +0530 Subject: [PATCH] Tighten span logging validation --- app/init/span.php | 10 ++++++- tests/unit/Span/SpanTest.php | 53 ++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/app/init/span.php b/app/init/span.php index 771e1ea8ac..6f52645da1 100644 --- a/app/init/span.php +++ b/app/init/span.php @@ -22,7 +22,15 @@ $addSentryExporter = function (string $loggingConfig, ?callable $sampler = null) throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Logging provider not supported. Logging is disabled'); } - $dsn = 'https://' . $loggingProvider->getPassword() . '@' . $loggingProvider->getHost() . '/' . ($loggingProvider->getUser() ?? ''); + $projectId = $loggingProvider->getUser(); + $apiKey = $loggingProvider->getPassword(); + $host = $loggingProvider->getHost(); + + if (empty($projectId) || empty($apiKey) || empty($host)) { + throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Invalid Sentry DSN. Logging is disabled'); + } + + $dsn = 'https://' . $apiKey . '@' . $host . '/' . $projectId; Span::addExporter( new Exporter\Sentry( diff --git a/tests/unit/Span/SpanTest.php b/tests/unit/Span/SpanTest.php index d40aa0f360..041cc6ba5f 100644 --- a/tests/unit/Span/SpanTest.php +++ b/tests/unit/Span/SpanTest.php @@ -40,4 +40,57 @@ class SpanTest extends TestCase $this->assertSame('worker.error', $exporter->exported[0]->getAction()); $this->assertSame($error, $exporter->exported[0]->getError()); } + + public function testSamplerSkipsUnmatchedSpan(): void + { + $exporter = new class () implements Exporter { + /** + * @var array + */ + public array $exported = []; + + public function export(Span $span): void + { + $this->exported[] = $span; + } + }; + + Span::addExporter( + exporter: $exporter, + sampler: fn (Span $span): bool => $span->get('appwrite.error.publish') === true, + ); + + $span = new Span('worker.error'); + $span->set('appwrite.error.publish', false); + $span->finish(); + + $this->assertCount(0, $exporter->exported); + } + + public function testSamplerExportsMatchedSpan(): void + { + $exporter = new class () implements Exporter { + /** + * @var array + */ + public array $exported = []; + + public function export(Span $span): void + { + $this->exported[] = $span; + } + }; + + Span::addExporter( + exporter: $exporter, + sampler: fn (Span $span): bool => $span->get('appwrite.error.publish') === true, + ); + + $span = new Span('worker.error'); + $span->set('appwrite.error.publish', true); + $span->finish(); + + $this->assertCount(1, $exporter->exported); + $this->assertSame('worker.error', $exporter->exported[0]->getAction()); + } }