Error Handling¶
Comprehensive error handling guide for TokenFlow.
Common Errors¶
OAuth Flow Errors¶
authorization_pending¶
User hasn't authorized the device code yet.
Handling: Continue polling (automatic in TokenFlow)
slow_down¶
Polling too frequently.
Handling: Increase polling interval by 5 seconds (automatic)
expired_token¶
Device code has expired (typically 15 minutes).
Handling: Restart the flow
access_denied¶
User denied authorization.
Handling: Inform user and exit
try:
token = await poll_for_token(device_code)
except Exception as e:
if "access_denied" in str(e):
print("Authorization denied by user")
sys.exit(1)
Network Errors¶
Timeout¶
All requests have 30-second timeout.
Connection Error¶
Unable to reach the service.
Token Errors¶
Expired Token¶
Token has expired.
token = load_token("token.json")
if token.is_expired():
print("Token expired, re-authenticating...")
token = await authenticate()
Invalid Token¶
Token is malformed or corrupted.
File System Errors¶
Token Not Found¶
No cached token available.
try:
token = load_token("token.json")
except FileNotFoundError:
print("No cached token, starting authentication...")
token = await authenticate()
Permission Denied¶
Cannot write token file.
Best Practices¶
1. Always Handle Errors¶
Never ignore errors in production code:
try:
token = await poll_for_token(device_code)
except Exception as e:
logger.error(f"Authentication failed: {e}")
raise
2. Provide User Feedback¶
Inform users about what's happening:
try:
token = await poll_for_token(device_code)
except Exception as e:
if "expired_token" in str(e):
print("⚠️ Device code expired. Please try again.")
elif "access_denied" in str(e):
print("❌ Authorization denied")
else:
print(f"❌ Error: {e}")
3. Implement Retry Logic¶
For transient errors:
for attempt in range(3):
try:
token = await poll_for_token(device_code)
break
except (ConnectionError, TimeoutError):
if attempt == 2:
raise
await asyncio.sleep(2 ** attempt)
4. Log Errors¶
Keep audit trail:
import logging
logger = logging.getLogger(__name__)
try:
token = await poll_for_token(device_code)
except Exception as e:
logger.exception("Authentication failed")
raise
Error Response Structure¶
OAuth error responses follow this structure:
{
"error": "authorization_pending",
"error_description": "The authorization request is still pending",
"error_uri": "https://docs.github.com/..."
}
Access fields in your error handler: