fix: Add DNS retry logic to Telegram bot
Problem: Python urllib3 throwing 'Failed to resolve trading-bot-v4' errors Root cause: Transient DNS resolution failures (similar to Node.js DNS issue) Solution: Added retry_request() wrapper with exponential backoff: - Retries DNS/connection errors up to 3 times - 2s → 4s → 8s delays between attempts - Same pattern as Node.js retryOperation() in drift/client.ts Applied to: - /status command (position fetching) - Manual trade execution (most critical) User request: Configure bot to handle DNS problems better Result: Telegram bot now self-recovers from transient DNS failures
This commit is contained in:
@@ -4,10 +4,37 @@ Telegram Trade Bot - SECURE Command-based
|
|||||||
Only responds to YOUR commands in YOUR chat
|
Only responds to YOUR commands in YOUR chat
|
||||||
"""
|
"""
|
||||||
import os
|
import os
|
||||||
|
import time
|
||||||
import requests
|
import requests
|
||||||
from telegram import Update
|
from telegram import Update
|
||||||
from telegram.ext import Application, CommandHandler, ContextTypes, MessageHandler, filters
|
from telegram.ext import Application, CommandHandler, ContextTypes, MessageHandler, filters
|
||||||
|
|
||||||
|
def retry_request(func, max_retries=3, initial_delay=2):
|
||||||
|
"""
|
||||||
|
Retry wrapper for DNS/connection failures
|
||||||
|
Similar to Node.js retryOperation() logic
|
||||||
|
"""
|
||||||
|
for attempt in range(max_retries):
|
||||||
|
try:
|
||||||
|
return func()
|
||||||
|
except (requests.exceptions.ConnectionError,
|
||||||
|
requests.exceptions.Timeout,
|
||||||
|
Exception) as e:
|
||||||
|
error_msg = str(e).lower()
|
||||||
|
# Check for transient DNS/connection errors
|
||||||
|
if 'name or service not known' in error_msg or \
|
||||||
|
'failed to resolve' in error_msg or \
|
||||||
|
'connection' in error_msg:
|
||||||
|
if attempt < max_retries - 1:
|
||||||
|
delay = initial_delay * (2 ** attempt)
|
||||||
|
print(f"⏳ DNS/connection error (attempt {attempt + 1}/{max_retries}): {e}", flush=True)
|
||||||
|
print(f" Retrying in {delay}s...", flush=True)
|
||||||
|
time.sleep(delay)
|
||||||
|
continue
|
||||||
|
# Non-transient error or max retries reached
|
||||||
|
raise
|
||||||
|
raise Exception(f"Max retries ({max_retries}) exceeded")
|
||||||
|
|
||||||
# Configuration
|
# Configuration
|
||||||
TELEGRAM_BOT_TOKEN = os.getenv('TELEGRAM_BOT_TOKEN')
|
TELEGRAM_BOT_TOKEN = os.getenv('TELEGRAM_BOT_TOKEN')
|
||||||
N8N_WEBHOOK_URL = os.getenv('N8N_WEBHOOK_URL')
|
N8N_WEBHOOK_URL = os.getenv('N8N_WEBHOOK_URL')
|
||||||
@@ -58,12 +85,12 @@ async def status_command(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
|||||||
print(f"📊 /status command received", flush=True)
|
print(f"📊 /status command received", flush=True)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Fetch positions from trading bot API
|
# Fetch positions from trading bot API with retry logic
|
||||||
response = requests.get(
|
response = retry_request(lambda: requests.get(
|
||||||
f"{TRADING_BOT_URL}/api/trading/positions",
|
f"{TRADING_BOT_URL}/api/trading/positions",
|
||||||
headers={'Authorization': f'Bearer {API_SECRET_KEY}'},
|
headers={'Authorization': f'Bearer {API_SECRET_KEY}'},
|
||||||
timeout=10
|
timeout=10
|
||||||
)
|
))
|
||||||
|
|
||||||
print(f"📥 API Response: {response.status_code}", flush=True)
|
print(f"📥 API Response: {response.status_code}", flush=True)
|
||||||
|
|
||||||
@@ -646,12 +673,12 @@ async def manual_trade_handler(update: Update, context: ContextTypes.DEFAULT_TYP
|
|||||||
try:
|
try:
|
||||||
print(f"🚀 Manual trade: {direction.upper()} {symbol_info['label']}{' (FORCED)' if force_trade else ''}", flush=True)
|
print(f"🚀 Manual trade: {direction.upper()} {symbol_info['label']}{' (FORCED)' if force_trade else ''}", flush=True)
|
||||||
|
|
||||||
response = requests.post(
|
response = retry_request(lambda: requests.post(
|
||||||
f"{TRADING_BOT_URL}/api/trading/execute",
|
f"{TRADING_BOT_URL}/api/trading/execute",
|
||||||
headers={'Authorization': f'Bearer {API_SECRET_KEY}'},
|
headers={'Authorization': f'Bearer {API_SECRET_KEY}'},
|
||||||
json=payload,
|
json=payload,
|
||||||
timeout=60,
|
timeout=60,
|
||||||
)
|
))
|
||||||
|
|
||||||
print(f"📥 Manual trade response: {response.status_code}", flush=True)
|
print(f"📥 Manual trade response: {response.status_code}", flush=True)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user