refactor: update payload validators to use closures for instantiation and improve error handling

This commit is contained in:
ArnabChatterjee20k
2026-05-06 12:10:50 +05:30
parent d043b4740e
commit 5eabeeea20
5 changed files with 26 additions and 33 deletions
+1 -9
View File
@@ -117,17 +117,9 @@ class Dispatcher
$validator = $validator();
}
if (!$validator->isValid($value)) {
// taking the error directly instead of the message attribute from the validator
// to avoid the race condition between coroutines modifying each others static attributes
// as the validator is a static class
$description = $validator->getDescription();
if (\is_callable([$validator, 'getValidationError'])) {
$description = $validator->getValidationError($value) ?? $description;
}
throw new Exception(
Exception::REALTIME_MESSAGE_FORMAT_INVALID,
\sprintf('%s: %s', $key, $description)
\sprintf('%s: %s', $key, $validator->getDescription())
);
}
}
@@ -21,7 +21,7 @@ class SubscribeHandler extends Action
->desc('Bulk subscribe to realtime channels')
->label(Dispatcher::LABEL_MESSAGE_TYPE, 'subscribe')
->label(Dispatcher::LABEL_PAYLOAD_SHAPE, Dispatcher::PAYLOAD_SHAPE_LIST)
->param('items', null, new SubscribePayloadValidator(), 'Subscriptions to add')
->param('items', null, fn () => new SubscribePayloadValidator(), 'Subscriptions to add')
->inject('connection')
->inject('realtime')
->inject('register')
@@ -17,7 +17,7 @@ class UnsubscribeHandler extends Action
->desc('Bulk remove subscriptions by id')
->label(Dispatcher::LABEL_MESSAGE_TYPE, 'unsubscribe')
->label(Dispatcher::LABEL_PAYLOAD_SHAPE, Dispatcher::PAYLOAD_SHAPE_LIST)
->param('items', null, new UnsubscribePayloadValidator(), 'Subscriptions to remove')
->param('items', null, fn () => new UnsubscribePayloadValidator(), 'Subscriptions to remove')
->inject('connection')
->inject('realtime')
->inject('register')
@@ -6,9 +6,11 @@ use Utopia\Validator;
class SubscribePayloadValidator extends Validator
{
protected string $description = 'Payload is not valid.';
public function getDescription(): string
{
return 'Payload is not valid.';
return $this->description;
}
public function isArray(): bool
@@ -22,33 +24,33 @@ class SubscribePayloadValidator extends Validator
}
public function isValid(mixed $value): bool
{
return $this->getValidationError($value) === null;
}
public function getValidationError(mixed $value): ?string
{
if (!\is_array($value) || !\array_is_list($value)) {
return 'Payload is not valid.';
$this->description = 'Payload is not valid.';
return false;
}
foreach ($value as $payload) {
if (!\is_array($payload)) {
return 'Each subscribe payload must be an object.';
$this->description = 'Each subscribe payload must be an object.';
return false;
}
if (!\array_key_exists('channels', $payload)) {
return 'channels is not present in payload.';
$this->description = 'channels is not present in payload.';
return false;
}
if (!\is_array($payload['channels']) || !\array_is_list($payload['channels'])) {
return 'channels is not a valid array.';
$this->description = 'channels is not a valid array.';
return false;
}
if (\array_key_exists('queries', $payload)
&& (!\is_array($payload['queries']) || !\array_is_list($payload['queries']))
) {
return 'queries is not a valid array.';
$this->description = 'queries is not a valid array.';
return false;
}
}
return null;
return true;
}
}
}
@@ -6,9 +6,11 @@ use Utopia\Validator;
class UnsubscribePayloadValidator extends Validator
{
protected string $description = 'Payload is not valid.';
public function getDescription(): string
{
return 'Payload is not valid.';
return $this->description;
}
public function isArray(): bool
@@ -22,14 +24,10 @@ class UnsubscribePayloadValidator extends Validator
}
public function isValid(mixed $value): bool
{
return $this->getValidationError($value) === null;
}
public function getValidationError(mixed $value): ?string
{
if (!\is_array($value) || !\array_is_list($value)) {
return 'Payload is not valid.';
$this->description = 'Payload is not valid.';
return false;
}
foreach ($value as $payload) {
@@ -39,10 +37,11 @@ class UnsubscribePayloadValidator extends Validator
|| !\is_string($payload['subscriptionId'])
|| $payload['subscriptionId'] === ''
) {
return 'Each unsubscribe payload must include a non-empty subscriptionId.';
$this->description = 'Each unsubscribe payload must include a non-empty subscriptionId.';
return false;
}
}
return null;
return true;
}
}