فصل ۱۴: مدیریت خطاها و بهبود پایداری ربات تلگرام

۱. مقدمه
حتی بهترین رباتها هم ممکن است با مشکلاتی مانند:
- قطع اینترنت
- خطا در API
- ورودیهای غیرمنتظره از کاربر
- خطا در پردازش دادهها
مواجه شوند.
اگر این خطاها مدیریت نشوند، ربات:
- از کار میافتد
- پاسخ نامناسب میدهد
- تجربه کاربر را خراب میکند
در این فصل یاد میگیریم:
- خطاها را شناسایی و لاگگیری کنیم.
- از کرش کردن کل ربات جلوگیری کنیم.
- تجربیات کاربر را حتی در خطاها بهبود دهیم.
۲. انواع خطا در ربات
| نوع خطا | مثال | روش مدیریت |
|---|---|---|
| خطای API | پاسخ ندادن یا Timeout | استفاده از try-except و تلاش مجدد |
| خطای کاربر | ارسال فایل به جای متن | بررسی نوع پیام |
| خطای منطقی | تقسیم بر صفر در کد | Validation قبل از پردازش |
| خطای کتابخانه | آپدیت کتابخانه و تغییر متدها | تست پس از تغییرات |
۳. مدیریت خطاهای ساده با try-except
مثال: API هواشناسی
import requests
def get_weather():
try:
url = "https://api.open-meteo.com/v1/forecast?latitude=35.7&longitude=51.4¤t_weather=true"
res = requests.get(url, timeout=5) # محدودیت زمان پاسخ
res.raise_for_status()
data = res.json()
return data["current_weather"]["temperature"]
except requests.exceptions.RequestException as e:
print(f"خطا در دریافت اطلاعات هواشناسی: {e}")
return None
📌 نکته: همیشه زمان Timeout را تعیین کنید تا درخواستها بیپایان نمانند.
۴. مدیریت خطاهای Handlerها در python-telegram-bot
کتابخانه python-telegram-bot امکان ثبت یک error handler دارد.
from telegram.error import NetworkError, BadRequest
from telegram.ext import ApplicationBuilder, CommandHandler, ContextTypes
async def error_handler(update, context: ContextTypes.DEFAULT_TYPE):
print(f"⚠ خطا: {context.error}")
try:
if update and update.message:
await update.message.reply_text("🚫 مشکلی پیش آمد، لطفاً دوباره تلاش کنید.")
except Exception as e:
print(f"خطای اضافی در error_handler: {e}")
app = ApplicationBuilder().token("TOKEN").build()
app.add_error_handler(error_handler)
📌 این روش اجازه نمیدهد که یک خطا باعث توقف کامل اجرای ربات شود.
۵. لاگگیری حرفهای (Logging)
لاگگیری برای پیدا کردن علت مشکلات حیاتی است.
import logging
logging.basicConfig(
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
level=logging.INFO
)
logger = logging.getLogger(__name__)
logger.info("ربات راهاندازی شد!")
📌 میتوانید لاگها را در فایل ذخیره کنید تا بعداً تحلیل شوند:
logging.basicConfig(
filename="bot.log",
filemode="a",
format="%(asctime)s - %(levelname)s - %(message)s",
level=logging.ERROR
)
۶. جلوگیری از توقف ربات با Exceptionهای کنترلنشده
به جای اینکه کل برنامه با یک خطا متوقف شود، از try-except سراسری استفاده کنید.
import sys
try:
# اجرای کد اصلی
app.run_polling()
except Exception as e:
print(f"خطای کلی: {e}")
sys.exit(1)
۷. ریکاوری خودکار (Self Recovery)
اگر ربات روی سرور یا سیستمعامل لینوکس است، میتوانید از:
- systemd
- supervisord
- یا سرویسهای ابری مثل Railway, Heroku
استفاده کنید تا در صورت کرش، بهصورت خودکار دوباره اجرا شود.
systemd سرویس نمونه:
[Service]
ExecStart=/usr/bin/python3 /path/to/bot.py
Restart=always
RestartSec=5
۸. مدیریت خطا در Job Queue
اگر در Job Queue خطایی رخ دهد، کل Job ممکن است متوقف شود. باید آن را مدیریت کرد.
async def safe_job(context):
try:
# کد job
await context.bot.send_message(context.job.chat_id, "Job موفق 👍")
except Exception as e:
print(f"خطا در job: {e}")
۹. نکات امنیتی برای پایداری
- ورودی کاربر را اعتبارسنجی کنید (مثلاً نگذارید کاربر لینک مخرب بفرستد).
- محدودیت نرخ (Rate Limit) تعیین کنید تا کاربر هر ثانیه صدها درخواست نفرستد.
- توکن ربات را عمومی نکنید.
۱۰. سوالات متداول
س: اگر API قطع باشد چه کنم؟
ج: باید پاسخ جایگزین (Fallback) داشته باشید یا پیام خطا به کاربر بدهید.
س: آیا باید همه پیامها در دیتابیس ذخیره شوند؟
ج: برای پایداری بیشتر بله، مخصوصاً پیامهای مهم.
س: چقدر خطا باید لاگ شود؟
ج: همه خطاهای مهم ولی نه جزییات حساس کاربر.
۱۱. اشتباهات رایج
| اشتباه | توضیح |
|---|---|
| نداشتن error handler | باعث توقف کامل ربات میشود |
| Timeout نداشتن در درخواستها | ممکن است ربات برای همیشه منتظر بماند |
| ذخیره نکردن لاگها | تحلیل مشکل غیرممکن میشود |
۱۲. نکات حرفهای
- از Sentry یا ابزارهای مانیتورینگ برای گرفتن خطا و هشدار آنی استفاده کنید.
- در Job Queue، نتیجه آخرین اجرا را ذخیره کنید تا دفعه بعد در صورت شکست، کاربر مطلع شود.
- یک دستور مخفی
/healthایجاد کنید که فقط ادمینها بتوانند بزنند تا وضعیت ربات را بررسی کنند.