idol-commons / backend /generation_errors.py
fffiloni's picture
Restore Hub ZeroGPU quota handshake and clarify recoverable errors
e4a8344 verified
Raw History Blame Contribute Delete
2.39 kB
"""Allowlisted, plain-text failures. Never return a raw model exception or HTML."""
import re
import time
from dataclasses import dataclass
from fastapi import HTTPException
@dataclass(frozen=True)
class Failure:
code: str
message: str
retry_at: float | None = None
def generation_failure(error, phase):
title = getattr(error, 'title', '')
if phase == 'inference' and title == 'ZeroGPU quota exceeded':
text = str(getattr(error, 'message', ''))[:4096]
message = 'Hugging Face could not allocate a GPU because your ZeroGPU quota is currently insufficient.'
quota = re.search(r'\((\d{1,5})s requested vs\. (\d{1,5}(?:\.\d{1,3})?)s left\)', text)
if quota:
message += f' This run requests {quota[1]} seconds; {quota[2]} seconds remain.'
wait = re.search(r'Try again in (?:(\d{1,2}) days?, )?(\d{1,3}):(\d{2}):(\d{2})(?:\.\d+)?\.', text)
retry_at = None
if wait:
seconds = int(wait[1] or 0)*86400 + int(wait[2])*3600 + int(wait[3])*60 + int(wait[4])
if 0 < seconds <= 7*86400:
retry_at = time.time()+seconds
message += f' Try again in about {max(1, (seconds+59)//60)} minutes.'
message += ' Your input and settings are saved. Open this app on Hugging Face and sign in to use your account quota.'
return Failure('gpu_quota', message, retry_at)
if phase == 'inference' and title in ('ZeroGPU queue timeout', 'ZeroGPU client error', 'ZeroGPU pending credits exceeded'):
return Failure('gpu_unavailable', 'A GPU is not available right now. Your input and settings are saved; try again shortly.')
if phase == 'inference' and title == 'ZeroGPU illegal duration':
return Failure('gpu_duration', 'This run exceeds the GPU duration allowed by your Hugging Face quota. Your input and settings are saved.')
if isinstance(error, HTTPException) and error.status_code == 401:
return Failure('session_expired', 'Your Hugging Face session has expired. Sign in again, then resume your saved input and settings.')
if phase == 'session':
return Failure('session_unavailable', 'Hugging Face could not verify your session. Your input and settings are saved; try again shortly.')
return Failure('generation_failed', 'Generation could not be completed. Your input and settings are saved; try again.')