Skip to content

Errors and limits

Every host response is either {"ok": true, "v": ...} or {"ok": false, "e": "<code>", "m": "<message>"}.

Code Python Rust (ErrorKind) C Meaning
— — — FG_OK = 0 success
denied Denied Denied FG_DENIED = 1 permission not granted or action forbidden
invalid Invalid Invalid FG_INVALID = 2 bad arguments
not_found NotFound NotFound FG_NOT_FOUND = 3 object not found
quota QuotaExceeded Quota FG_QUOTA = 4 quota used up
limit LimitExceeded Limit FG_LIMIT = 5 rate or size limit exceeded
unavailable Unavailable Unavailable FG_UNAVAILABLE = 6 unavailable right now
anything else Failed Failed FG_FAILED = 7 other failure
— — Transport FG_TRANSPORT = 8 the host call failed

Rust also has Cancelled for cancelled calls.

Network transport failures (blocked, dns, connect, tls, timeout, closed, response, redirect) arrive as Failed with the specific name in .code; see Network operations.

All Python exceptions inherit from FreshgramError and have code and message attributes.

try:
freshgram.messages.send(chat, "hi")
except freshgram.Denied:
freshgram.ui.toast("The messages.send permission is needed")
except freshgram.LimitExceeded:
pass # too often

The m text of many failures is fixed, so you can recognise it. In Python it is e.message, and str(e) is "code: message".

Operation Message (code)
any operation denied: a permission id such as "messages.send", or “this chat”, “this user”, “only right after a user action”
rate limits limit: “messages are sent too often”, “this is done too often”, “toasts are shown too often”, “notifications are shown too often”, “pictures are processed too often”, “usernames are resolved too often” (users.resolve, channels.resolve), “members are moderated too often” (chats.ban, chats.unban), “members are listed too often” (chats.members, chats.admins), “bots are asked too often” (bots.inline_query, bots.press_button), “windows are updated too often”
messages.react “the reaction was not set”
messages.forward “the messages were not forwarded”
chats.mark_read “the chat was not marked as read”
chats.action “the action was not sent” (an unknown kind is checked by the app, not by the host)
chats.mute, chats.archive, chats.pin “the chat was not changed”
users.block, users.unblock “the user was not changed”
chats.ban, chats.unban “the member was not changed”
ghost.set “ghost mode was not changed”
bots.send_inline_result “the result was not sent”
stickers.send “the sticker was not sent”
notify.show “the notification was not shown”
clipboard.write “the clipboard was not changed”
composer.insert “the text was not inserted”
fs.list, fs.stat, fs.read, fs.write, fs.mkdir / fs.remove, fs.rename “the folder was not listed”, “no such file”, “the file was not read”, “the file was not written”, “the change was not made”, “the file was not renamed”
files.pick, files.save invalid “title or filter” / “name or data”; “the file was not read” / “the file was not saved”
storage.get, storage.set, storage.delete invalid “key” (empty, over 128 bytes, a control byte or not text)
net.ws.connect invalid “url” (missing, not text or over 2048 bytes)
net.socket.*, net.ws.* not_found “socket” for an unknown or closed socket id
ui.toast invalid “undo needs an action” for undo=True without an action
unavailable “awaitable calls”, “toast actions”, “windows”, “timers”, “network” and similar: the app lacks that service

For the operations from messages.react to fs.rename the code is the one the app reports (usually failed); only the message is fixed by the host.

Some wrong arguments do not raise Invalid. An integer argument that has another type is treated as absent and takes its default:

  • limit of storage.keys (100);
  • max of net.socket.recv (65507) and timeout of net.fetch, sockets and WebSockets (10000 for connecting and sending, 1000 for receiving);
  • net.fetch method that is not text or is longer than 8 bytes becomes GET (other text, such as "get", is Invalid).

Out-of-range numbers are clamped instead of rejected (for example a timeout over 30000 ms for a socket). The exact rules are in each operation’s page.

Exact values depend on the operation and are described with it. For example: messages with media up to 100 MiB, images up to 16 MiB and 8192 pixels per side, at most 32 pending async calls, at most 32 timers, a notification no more than once in 5 seconds, users.resolve once per second.