mirror of
https://github.com/BushlanovDev/max-bot-api-client-php.git
synced 2026-10-08 21:08:52 +00:00
Skip updates that do not fit their model instead of crashing
#17 made unsupported update types silent: createUpdate() throws a LogicException, and createUpdateList() and WebhookHandler log it and skip the update. An update of a known type whose payload no longer fits the model (the API made a field optional, added an enum value) fails earlier, with a TypeError or ValueError from the model constructor, and nothing catches those: - createUpdateList() lets it out of getUpdates(), and LongPollingHandler::handle() catches only \Exception, so the loop stops and restarts into the same batch - WebhookHandler answers 500 and MAX keeps retrying createUpdate() now turns TypeError and ValueError into a LogicException (the original one kept as previous) and logs a warning with the payload, so the existing silent mode skips such an update. Errors thrown by user handlers are not affected.
This commit is contained in:
+37
-21
@@ -75,6 +75,8 @@ use LogicException;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Psr\Log\NullLogger;
|
||||
use ReflectionException;
|
||||
use TypeError;
|
||||
use ValueError;
|
||||
|
||||
/**
|
||||
* Creates DTOs from raw associative arrays returned by the API client.
|
||||
@@ -375,27 +377,41 @@ readonly class ModelFactory
|
||||
*/
|
||||
public function createUpdate(array $data): AbstractUpdate
|
||||
{
|
||||
return match (UpdateType::tryFrom($data['update_type'] ?? '')) {
|
||||
UpdateType::MessageCreated => MessageCreatedUpdate::fromArray($data),
|
||||
UpdateType::MessageCallback => MessageCallbackUpdate::fromArray($data),
|
||||
UpdateType::MessageEdited => MessageEditedUpdate::fromArray($data),
|
||||
UpdateType::MessageRemoved => MessageRemovedUpdate::fromArray($data),
|
||||
UpdateType::BotAdded => BotAddedToChatUpdate::fromArray($data),
|
||||
UpdateType::BotRemoved => BotRemovedFromChatUpdate::fromArray($data),
|
||||
UpdateType::DialogMuted => DialogMutedUpdate::fromArray($data),
|
||||
UpdateType::DialogUnmuted => DialogUnmutedUpdate::fromArray($data),
|
||||
UpdateType::DialogCleared => DialogClearedUpdate::fromArray($data),
|
||||
UpdateType::DialogRemoved => DialogRemovedUpdate::fromArray($data),
|
||||
UpdateType::UserAdded => UserAddedToChatUpdate::fromArray($data),
|
||||
UpdateType::UserRemoved => UserRemovedFromChatUpdate::fromArray($data),
|
||||
UpdateType::BotStarted => BotStartedUpdate::fromArray($data),
|
||||
UpdateType::BotStopped => BotStoppedUpdate::fromArray($data),
|
||||
UpdateType::ChatTitleChanged => ChatTitleChangedUpdate::fromArray($data),
|
||||
UpdateType::MessageChatCreated => MessageChatCreatedUpdate::fromArray($data),
|
||||
default => throw new LogicException(
|
||||
'Unknown or unsupported update type received: ' . ($data['update_type'] ?? 'none')
|
||||
),
|
||||
};
|
||||
try {
|
||||
return match (UpdateType::tryFrom($data['update_type'] ?? '')) {
|
||||
UpdateType::MessageCreated => MessageCreatedUpdate::fromArray($data),
|
||||
UpdateType::MessageCallback => MessageCallbackUpdate::fromArray($data),
|
||||
UpdateType::MessageEdited => MessageEditedUpdate::fromArray($data),
|
||||
UpdateType::MessageRemoved => MessageRemovedUpdate::fromArray($data),
|
||||
UpdateType::BotAdded => BotAddedToChatUpdate::fromArray($data),
|
||||
UpdateType::BotRemoved => BotRemovedFromChatUpdate::fromArray($data),
|
||||
UpdateType::DialogMuted => DialogMutedUpdate::fromArray($data),
|
||||
UpdateType::DialogUnmuted => DialogUnmutedUpdate::fromArray($data),
|
||||
UpdateType::DialogCleared => DialogClearedUpdate::fromArray($data),
|
||||
UpdateType::DialogRemoved => DialogRemovedUpdate::fromArray($data),
|
||||
UpdateType::UserAdded => UserAddedToChatUpdate::fromArray($data),
|
||||
UpdateType::UserRemoved => UserRemovedFromChatUpdate::fromArray($data),
|
||||
UpdateType::BotStarted => BotStartedUpdate::fromArray($data),
|
||||
UpdateType::BotStopped => BotStoppedUpdate::fromArray($data),
|
||||
UpdateType::ChatTitleChanged => ChatTitleChangedUpdate::fromArray($data),
|
||||
UpdateType::MessageChatCreated => MessageChatCreatedUpdate::fromArray($data),
|
||||
default => throw new LogicException(
|
||||
'Unknown or unsupported update type received: ' . ($data['update_type'] ?? 'none')
|
||||
),
|
||||
};
|
||||
} catch (TypeError|ValueError $e) {
|
||||
// The update type is known, but its payload does not fit the model: the API has
|
||||
// changed a field. Skip it like an unsupported update, so a webhook or a long-polling
|
||||
// loop does not stop on it, but log it louder.
|
||||
$message = sprintf(
|
||||
'Failed to parse update of type %s: %s',
|
||||
is_string($data['update_type'] ?? null) ? $data['update_type'] : 'none',
|
||||
$e->getMessage(),
|
||||
);
|
||||
$this->logger->warning($message, ['payload' => $data, 'exception' => $e]);
|
||||
|
||||
throw new LogicException($message, 0, $e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user