Skip to content

Error Handling ​

VibeGram provides a global error catcher and typed error classes so bot failures can be logged, classified, and reported to users without crashing the process.

Error Hierarchy ​

text
Error
  VibeGramError
    TelegramApiError
    NetworkError
    RateLimitError
    InvalidTokenError
    WebAppValidationError
    ConversationTimeoutError

Global Error Handler ​

typescript
bot.catch((err, ctx) => {
    console.error(`Error for update ${ctx.update.update_id}:`, err);
    ctx.reply('An error occurred. Please try again.').catch(() => {});
});

If no bot.catch() handler is registered, VibeGram logs the error to console.error.

Typed Error Handling ​

typescript
import {
    ConversationTimeoutError,
    InvalidTokenError,
    NetworkError,
    RateLimitError,
    TelegramApiError,
    VibeGramError,
} from 'vibegram';

bot.catch(async (err, ctx) => {
    if (err instanceof TelegramApiError) {
        console.error(`Telegram API ${err.errorCode}: ${err.description}`);

        if (err.errorCode === 403) {
            console.log(`User ${ctx.from?.id} may have blocked the bot`);
            return;
        }

        await ctx.reply('Telegram rejected that request.').catch(() => {});
        return;
    }

    if (err instanceof RateLimitError) {
        console.warn(`Rate limited. Retry after ${err.retryAfter}s`);
        return;
    }

    if (err instanceof NetworkError) {
        console.error('Network failure:', err.originalError?.message);
        return;
    }

    if (err instanceof ConversationTimeoutError) {
        await ctx.reply('Conversation expired. Please start again.').catch(() => {});
        return;
    }

    if (err instanceof VibeGramError) {
        console.error(`[${err.code}] ${err.message}`);
        return;
    }

    console.error('Unknown error:', err);
});

Error Properties ​

TelegramApiError ​

PropertyTypeDescription
messagestringError message
errorCodenumberTelegram/API status-like code
descriptionstringTelegram API description
codestringStable VibeGram error code

RateLimitError ​

PropertyTypeDescription
retryAfternumberSeconds until retry is allowed
codestringStable VibeGram error code

NetworkError ​

PropertyTypeDescription
originalError`Errorundefined`
codestringStable VibeGram error code

ConversationTimeoutError ​

PropertyTypeDescription
chatId`numberstring
codestringStable VibeGram error code

Local Error Handling ​

Catch expected failures inside a handler and rethrow unexpected ones to the global handler:

typescript
bot.command('ban', async ctx => {
    try {
        await ctx.banChatMember(targetId);
        await ctx.reply('User banned.');
    } catch (err) {
        if (err instanceof TelegramApiError && err.errorCode === 400) {
            await ctx.reply('User was not found in this chat.');
            return;
        }

        throw err;
    }
});

Launch Token Errors ​

launch() validates the bot token with getMe() before starting. Handle InvalidTokenError near your process entry point:

typescript
import { InvalidTokenError } from 'vibegram';

try {
    await bot.launch();
} catch (err) {
    if (err instanceof InvalidTokenError) {
        console.error('Bot token is invalid.');
        process.exit(1);
    }

    throw err;
}

Error Isolation ​

Polling awaits each update before moving to the next one, so one failed update does not create an unhandled rejection for the rest of the batch.

Webhook adapters catch update-processing errors and return 500 Internal Server Error; use observability hooks and bot.catch() for logging and safe user responses.

Best Practices ​

  • Register bot.catch() before production deployment.
  • Log structured metadata such as update_id, chat.id, and error class.
  • Avoid sending stack traces or raw error messages to users.
  • Do not rethrow from bot.catch() unless a supervisor must restart the process.

Released under the ISC License.