File size: 2,388 Bytes
e4a8344
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
"""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.')