telega/error
Types
What a Bot API failure actually was, in a form you can case on.
The Bot API has no structured error codes: everything but the HTTP status
arrives as English prose in description. classify does that reading
once, so call sites match on a constructor instead of spelling substrings
of their own. Every is_* predicate in this module is a one-line wrapper
over it.
case error.classify(err) {
error.BotBlocked | error.UserDeactivated -> forget_user(chat_id)
error.TooManyRequests(retry_after:) -> sleep(retry_after * 1000)
error.ChatMigrated(new_chat_id:) -> resend_to(new_chat_id)
_ -> log(err)
}
pub type ApiErrorKind {
BotBlocked
BotKicked
UserDeactivated
ChatNotFound
ChatWriteForbidden
MessageNotModified
MessageNotFound
MessageCantBeEdited
MessageTooLong
TooManyRequests(retry_after: Int)
ChatMigrated(new_chat_id: Int)
Unauthorized
Forbidden
BadRequest
ServerError
Other
}
Constructors
-
BotBlockedThe user blocked the bot (403). They can unblock it later, so the chat id stays valid.
-
BotKickedThe bot was removed from the chat (403 “bot was kicked” / “bot is not a member”).
-
UserDeactivatedThe account is gone for good (403 “user is deactivated”).
-
ChatNotFoundTelegram does not know this chat (400 “chat not found”) — a wrong id, or a user who never started the bot.
-
ChatWriteForbiddenThe bot is in the chat but may not post there: restricted by an admin, a channel it is not an admin of, or a bot-to-bot chat.
-
MessageNotModifiedThe edit was a no-op: new content equals the current one. Safe to treat as success.
-
MessageNotFoundThe message to edit no longer exists (deleted by the user or too old).
-
MessageCantBeEditedThe message exists but cannot be edited (e.g. not sent by the bot).
-
MessageTooLongThe text or caption exceeded Telegram’s length limit. Split it and resend.
-
TooManyRequests(retry_after: Int)Flood control (429).
retry_afteris what Telegram asked for, in seconds, or0when it sent noparameters. -
ChatMigrated(new_chat_id: Int)The group became a supergroup and got a new id. Resend to
new_chat_id. -
UnauthorizedThe token is wrong or revoked (401).
-
ForbiddenA 403 this module does not recognize more precisely.
-
BadRequestA 400 this module does not recognize more precisely.
-
ServerErrorTelegram’s own failure (5xx). Worth retrying.
-
OtherAnything else, including every non-API
TelegaError(a transport failure, a decode error, an actor that would not start).
pub type TelegaError {
TelegramApiError(
error_code: Int,
description: String,
parameters: option.Option(types.ResponseParameters),
)
FetchError(error: String)
JsonDecodeError(error: json.DecodeError)
BotHandleUpdateError(reason: String)
ApiToRequestConvertError
SetWebhookError
RegistryStartError(reason: String)
BotStartError(reason: actor.StartError)
ChatInstanceStartError(reason: actor.StartError)
FileNotFoundError
DecodeUpdateError(reason: String)
UnknownUpdateError(update: types.Update)
ActorError(reason: String)
RouterError(reason: String)
SupervisorStartError(reason: actor.StartError)
ShutdownError(reason: String)
}
Constructors
-
TelegramApiError( error_code: Int, description: String, parameters: option.Option(types.ResponseParameters), )Returned by Bot API if server returns
ok: false, indicating that your API request was invalid and failed.parametersis Telegram’s ownResponseParameterswhen it sent one —retry_afteron a flood wait,migrate_to_chat_idwhen a group became a supergroup. Read them withretry_after/migrate_to_chat_id. -
FetchError(error: String)Returned if the Bot API server could not be reached or the request failed
-
JsonDecodeError(error: json.DecodeError)Returned if the JSON response from the Bot API could not be decoded
-
BotHandleUpdateError(reason: String)Returned if the bot failed to call
handle_update -
ApiToRequestConvertErrorReturned if the bot failed to convert API request to HTTP request
-
SetWebhookError -
RegistryStartError(reason: String) -
BotStartError(reason: actor.StartError) -
ChatInstanceStartError(reason: actor.StartError) -
FileNotFoundError -
DecodeUpdateError(reason: String) -
UnknownUpdateError(update: types.Update)Occurs when the update is not handled by any handler
-
ActorError(reason: String)General actor error (e.g., from polling)
-
RouterError(reason: String) -
SupervisorStartError(reason: actor.StartError) -
ShutdownError(reason: String)
Values
pub fn classify(error error: TelegaError) -> ApiErrorKind
Read a Bot API failure into an ApiErrorKind.
Non-API errors — transport, decoding, startup — classify as Other: they
carry no Telegram status to read.
pub fn is_bot_blocked(error error: TelegaError) -> Bool
The user blocked the bot (403). They can unblock it later, so the chat id stays valid.
pub fn is_bot_kicked(error error: TelegaError) -> Bool
The bot was removed from the chat (403 “bot was kicked” / “bot is not a member”).
pub fn is_chat_not_found(error error: TelegaError) -> Bool
Telegram does not know this chat (400 “chat not found”) — a wrong id, or a user who never started the bot.
pub fn is_chat_unreachable(error error: TelegaError) -> Bool
This chat cannot be delivered to right now: blocked, deactivated, kicked, unknown to Telegram, or one the bot may not write in. Retrying the same call will not help, which is what separates it from a flood wait or a 5xx.
pub fn is_message_cant_be_edited(
error error: TelegaError,
) -> Bool
The message exists but cannot be edited (e.g. not sent by the bot).
pub fn is_message_not_found(error error: TelegaError) -> Bool
The message to edit no longer exists (deleted by the user or too old).
pub fn is_message_not_modified(error error: TelegaError) -> Bool
The edit was a no-op: new content equals the current one. Safe to treat as success.
pub fn is_message_too_long(error error: TelegaError) -> Bool
The text or caption was longer than Telegram accepts (400 “message is too long”).
pub fn is_user_deactivated(error error: TelegaError) -> Bool
The account is gone for good (403 “user is deactivated”).
pub fn migrate_to_chat_id(
error error: TelegaError,
) -> option.Option(Int)
The supergroup id this chat was migrated to, as Telegram reported it in
parameters.migrate_to_chat_id. Resend to this id instead.
pub fn retry_after(
error error: TelegaError,
) -> option.Option(Int)
Seconds to wait before repeating the request, as Telegram reported them in
parameters.retry_after (flood control). None for every other error.
pub fn to_string(error: TelegaError) -> String
pub fn try(
result: Result(a, TelegaError),
to to_error: fn(TelegaError) -> e,
fun fun: fn(a) -> Result(b, e),
) -> Result(b, e)
Helper to replace result.try for api call and error mapping.