Skip to main content

Overview

Proper error handling is crucial for building reliable Telegram bots and clients. Gogram provides comprehensive error handling mechanisms.

Error Categories

Telegram API errors are categorized by HTTP-like status codes:

303 - SeeOther

Redirect to another data center or endpoint

400 - BadRequest

Invalid request parameters or malformed data

401 - Unauthorized

Authentication required or session expired

403 - Forbidden

Access denied or insufficient permissions

406 - NotAcceptable

Request not acceptable (e.g., duplicate message)

420 - Flood

Too many requests, rate limiting active

500 - InternalServerError

Telegram server error, retry later

Common Error Examples

  • 400 - BadRequest
  • 401 - Unauthorized
  • 403 - Forbidden
  • 420 - Flood
  • 500 - Internal
// PEER_ID_INVALID
_, err := client.SendMessage(invalid_id, "Hello")
if err != nil && strings.Contains(err.Error(), "PEER_ID_INVALID") {
    fmt.Println("Invalid chat or user ID")
}

// MESSAGE_TOO_LONG
_, err = client.SendMessage("me", veryLongText)
if err != nil && strings.Contains(err.Error(), "MESSAGE_TOO_LONG") {
    fmt.Println("Message exceeds 4096 characters")
}

Error Types

Connection Errors

client, err := telegram.NewClient(telegram.ClientConfig{
    AppID: 6, AppHash: "app_hash",
})
if err != nil {
    log.Fatalf("Failed to create client: %v", err)
}

err = client.Conn()
if err != nil {
    log.Fatalf("Failed to connect: %v", err)
}

Handling API Errors

Every API call returns two values: the result and an error. Always check the error before using the result.
user, err := client.GetMe()
if err != nil {
    log.Fatalf("API error: %v", err)
}

channel, err := client.ChannelsGetFullChannel("@somechannel")
if err != nil {
    log.Fatalf("API error: %v", err)
}

Error Handler

The client config asks for a global error handler function that gets called for unhandled errors in event handlers.
client, err := telegram.NewClient(telegram.ClientConfig{
    AppID: 6, AppHash: "app_hash",
    ErrorHandler: func(err error) {
        log.Printf("Global error: %v", err)
    },
})

Handling Flood Waits

Some API calls may return a FLOOD_WAIT error if you exceed rate limits. Implement retry logic with exponential backoff. The client config also allows setting a custom flood wait handler.
client, err := telegram.NewClient(telegram.ClientConfig{
    AppID: 6, AppHash: "app_hash",
    FloodHandler: func(err error) bool {
        log.Printf("Flood wait error: %v", err)
        // do the necessary wait here
        return true // return true to retry the request
        // return false to abort the request
    }
})

Best Practices

Always Check Errors

Never ignore errors - always check and handle them

Use Global Error Handler

Implement a global error handler for unhandled errors

Complete Example

package main

import (
    "fmt"
    "log"
    "strings"
    "time"
    "github.com/amarnathcjd/gogram/telegram"
)

func main() {
    client, err := telegram.NewClient(telegram.ClientConfig{
        AppID: 6, AppHash: "app_hash",
        ErrorHandler: func(err error) {
            log.Printf("Global error: %v", err)
        },
        FloodHandler: func(err error) bool {
            log.Printf("Flood wait error: %v", err)
            return true
        },
    })
    if err != nil {
        log.Fatalf("Failed to create client: %v", err)
    }

    if err := client.Conn(); err != nil {
        log.Fatalf("Connection failed: %v", err)
    }

    if err := client.LoginBot("bot_token"); err != nil {
        log.Fatalf("Login failed: %v", err)
    }

    client.On("message", func(m *telegram.NewMessage) error {
        if len(m.Text()) == 0 {
            return fmt.Errorf("empty message")
        }

        return nil
    })

    client.Idle()
}

Next Steps