From 42144ab9a0e373ed3c9d64e2a6c4521d8e1eedcf Mon Sep 17 00:00:00 2001 From: ArnabChatterjee20k Date: Mon, 18 May 2026 21:23:21 +0530 Subject: [PATCH 1/4] added category to the presences scopes --- app/config/scopes/project.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/config/scopes/project.php b/app/config/scopes/project.php index b27f328308..d0d9ca21bf 100644 --- a/app/config/scopes/project.php +++ b/app/config/scopes/project.php @@ -381,8 +381,10 @@ return [ ], 'presences.read' => [ 'description' => 'Access to read your project\'s presences', + 'category' => 'Presences' ], 'presences.write' => [ 'description' => 'Access to create, update, and delete your project\'s presences', + 'category' => 'Presences' ], ]; From 6f28f2e4f7408e517f12795711e76acb752947e4 Mon Sep 17 00:00:00 2001 From: ArnabChatterjee20k Date: Mon, 18 May 2026 21:26:21 +0530 Subject: [PATCH 2/4] linting --- app/config/scopes/project.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/config/scopes/project.php b/app/config/scopes/project.php index d0d9ca21bf..cd50abd57b 100644 --- a/app/config/scopes/project.php +++ b/app/config/scopes/project.php @@ -381,10 +381,10 @@ return [ ], 'presences.read' => [ 'description' => 'Access to read your project\'s presences', - 'category' => 'Presences' + 'category' => 'Presences', ], 'presences.write' => [ 'description' => 'Access to create, update, and delete your project\'s presences', - 'category' => 'Presences' + 'category' => 'Presences', ], ]; From 349db8d370852029a16e909b067429a1f786d5fb Mon Sep 17 00:00:00 2001 From: ArnabChatterjee20k Date: Mon, 18 May 2026 21:49:13 +0530 Subject: [PATCH 3/4] fix: improve error handling for Utopia DB exceptions in realtime API --- app/realtime.php | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/app/realtime.php b/app/realtime.php index b34dd9f420..b677b525c4 100644 --- a/app/realtime.php +++ b/app/realtime.php @@ -35,7 +35,9 @@ use Utopia\Database\Adapter\Pool as DatabasePool; use Utopia\Database\Database; use Utopia\Database\DateTime; use Utopia\Database\Document; +use Utopia\Database\Exception\Authorization as AuthorizationException; use Utopia\Database\Exception\Query as QueryException; +use Utopia\Database\Exception\Timeout as TimeoutException; use Utopia\Database\Helpers\ID; use Utopia\Database\Helpers\Role; use Utopia\Database\Query; @@ -374,7 +376,16 @@ if (!function_exists('logError')) { $logger = $register->get('realtimeLogger'); - if ($logger && !$error instanceof Exception) { + // Match HTTP semantics (app/controllers/general.php): AppwriteException uses its + // configured publish flag; everything else publishes only for code 0 or >= 500. + // Without this, expected client errors (e.g. Utopia DB Authorization) hit Sentry. + if ($error instanceof Exception) { + $publish = $error->isPublishable(); + } else { + $publish = $error->getCode() === 0 || $error->getCode() >= 500; + } + + if ($logger && $publish) { $version = System::getEnv('_APP_VERSION', 'UNKNOWN'); $log = new Log(); @@ -990,6 +1001,16 @@ $server->onOpen(function (int $connection, SwooleRequest $request) use ($server, $success = true; } catch (Throwable $th) { + Span::error($th); + + // Convert known Utopia DB exceptions to AppwriteException so isPublishable() + // suppresses expected client errors (permission denied, query timeout) from Sentry. + if ($th instanceof AuthorizationException) { + $th = new AppwriteException(AppwriteException::USER_UNAUTHORIZED, previous: $th); + } elseif ($th instanceof TimeoutException) { + $th = new AppwriteException(AppwriteException::DATABASE_TIMEOUT, previous: $th); + } + logError($th, 'realtime', project: $project, user: $logUser, authorization: $authorization); // Handle SQL error code is 'HY000' @@ -1025,7 +1046,6 @@ $server->onOpen(function (int $connection, SwooleRequest $request) use ($server, Console::error('[Error] Code: ' . $response['data']['code']); Console::error('[Error] Message: ' . $response['data']['message']); } - Span::error($th); } finally { Span::add('realtime.success', $success); Span::add('realtime.response_code', $responseCode); @@ -1171,6 +1191,16 @@ $server->onMessage(function (int $connection, string $message) use ($container, $success = true; } catch (Throwable $th) { + Span::error($th); + + // Convert known Utopia DB exceptions to AppwriteException so isPublishable() + // suppresses expected client errors (permission denied, query timeout) from Sentry. + if ($th instanceof AuthorizationException) { + $th = new AppwriteException(AppwriteException::USER_UNAUTHORIZED, previous: $th); + } elseif ($th instanceof TimeoutException) { + $th = new AppwriteException(AppwriteException::DATABASE_TIMEOUT, previous: $th); + } + logError($th, 'realtimeMessage', project: $project, authorization: $authorization); $code = $th->getCode(); if (!is_int($code)) { @@ -1200,7 +1230,6 @@ $server->onMessage(function (int $connection, string $message) use ($container, if ($th->getCode() === 1008) { $server->close($connection, $th->getCode()); } - Span::error($th); } finally { Span::add('realtime.success', $success); Span::add('realtime.response_code', $responseCode); From 4d3c60b36c475ada888afc31b944580551cf68fb Mon Sep 17 00:00:00 2001 From: ArnabChatterjee20k Date: Mon, 18 May 2026 21:53:06 +0530 Subject: [PATCH 4/4] updated --- app/realtime.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/realtime.php b/app/realtime.php index b677b525c4..73e7ab025a 100644 --- a/app/realtime.php +++ b/app/realtime.php @@ -379,7 +379,7 @@ if (!function_exists('logError')) { // Match HTTP semantics (app/controllers/general.php): AppwriteException uses its // configured publish flag; everything else publishes only for code 0 or >= 500. // Without this, expected client errors (e.g. Utopia DB Authorization) hit Sentry. - if ($error instanceof Exception) { + if ($error instanceof AppwriteException) { $publish = $error->isPublishable(); } else { $publish = $error->getCode() === 0 || $error->getCode() >= 500;