0
# Error Handling
1
2
Comprehensive exception system for handling authentication errors, application errors, and communication failures with detailed error information.
3
4
## Capabilities
5
6
### Authentication Errors
7
8
Handle authentication and authorization failures when connecting to protected Gradio applications.
9
10
```python { .api }
11
class AuthenticationError(ValueError):
12
"""
13
Raised when the client is unable to authenticate itself to a Gradio app
14
due to invalid or missing credentials.
15
16
This exception occurs when:
17
- Invalid or expired Hugging Face token for private Spaces
18
- Missing authentication credentials for protected apps
19
- Token lacks required permissions for Space operations
20
21
Inherits from ValueError for standard error handling patterns.
22
"""
23
pass
24
```
25
26
### Application Errors
27
28
Handle errors raised by the upstream Gradio application during prediction or processing.
29
30
```python { .api }
31
class AppError(ValueError):
32
"""
33
Raised when the upstream Gradio app throws an error because of the
34
value submitted by the client.
35
36
This exception provides detailed error information and display options
37
for debugging and user interaction.
38
"""
39
40
def __init__(
41
self,
42
message: str = "Error raised.",
43
duration: float | None = 10,
44
visible: bool = True,
45
title: str = "Error",
46
print_exception: bool = True,
47
):
48
"""
49
Initialize an AppError with detailed error information.
50
51
Parameters:
52
- message: The error message to be displayed to the user. Can be HTML.
53
- duration: Duration in seconds to display error. None/0 for persistent display.
54
- visible: Whether the error message should be displayed in the UI.
55
- title: The title to be displayed at the top of the error modal.
56
- print_exception: Whether to print traceback to console when raised.
57
"""
58
self.title = title
59
self.message = message
60
self.duration = duration
61
self.visible = visible
62
self.print_exception = print_exception
63
super().__init__(self.message)
64
```
65
66
### Communication Errors
67
68
Handle network and communication failures during client-server interactions.
69
70
```python { .api }
71
class TooManyRequestsError(Exception):
72
"""
73
Raised when the API returns a 429 status code.
74
75
Indicates rate limiting is in effect and requests should be
76
throttled or retried after a delay.
77
"""
78
pass
79
80
class QueueError(Exception):
81
"""
82
Raised when the queue is full or there is an issue adding a job to the queue.
83
84
This can occur when:
85
- Queue is full or unavailable
86
- Job submission fails
87
- Queue processing errors
88
"""
89
pass
90
91
class InvalidAPIEndpointError(Exception):
92
"""
93
Raised when the API endpoint is invalid.
94
95
This occurs when:
96
- Specified api_name doesn't exist in the Gradio app
97
- fn_index is out of range
98
- Endpoint configuration is malformed
99
"""
100
pass
101
102
class SpaceDuplicationError(Exception):
103
"""
104
Raised when something goes wrong with a Space Duplication.
105
106
This can occur when:
107
- Source Space doesn't exist or is inaccessible
108
- Insufficient permissions for duplication
109
- Hardware requirements cannot be met
110
- Network issues during duplication process
111
"""
112
pass
113
```
114
115
### Serialization Errors
116
117
Handle errors related to data serialization and deserialization.
118
119
```python { .api }
120
class SerializationSetupError(ValueError):
121
"""
122
Raised when a serializers cannot be set up correctly.
123
124
This occurs when:
125
- Unsupported data types in predictions
126
- Serialization format incompatibilities
127
- Missing required serialization components
128
"""
129
pass
130
```
131
132
## Usage Examples
133
134
### Basic Error Handling
135
136
```python
137
from gradio_client import Client
138
from gradio_client.exceptions import AuthenticationError, AppError
139
140
try:
141
# Attempt to connect to a private Space
142
client = Client("username/private-space", hf_token="invalid_token")
143
result = client.predict("test input")
144
145
except AuthenticationError as e:
146
print(f"Authentication failed: {e}")
147
print("Please check your Hugging Face token")
148
149
except AppError as e:
150
print(f"Application error: {e.message}")
151
print(f"Error title: {e.title}")
152
if e.print_exception:
153
import traceback
154
traceback.print_exc()
155
```
156
157
### Comprehensive Error Handling
158
159
```python
160
from gradio_client import Client
161
from gradio_client.exceptions import (
162
AuthenticationError,
163
AppError,
164
TooManyRequestsError,
165
SerializationSetupError
166
)
167
import time
168
import httpx
169
170
def robust_prediction(space_id: str, input_data, max_retries: int = 3):
171
"""Make a prediction with comprehensive error handling and retries."""
172
173
for attempt in range(max_retries):
174
try:
175
client = Client(space_id)
176
return client.predict(input_data, api_name="/predict")
177
178
except AuthenticationError as e:
179
print(f"Authentication error: {e}")
180
# Don't retry authentication errors - fix credentials instead
181
raise
182
183
except TooManyRequestsError as e:
184
print(f"Rate limited (attempt {attempt + 1}/{max_retries})")
185
if attempt < max_retries - 1:
186
# Exponential backoff
187
wait_time = 2 ** attempt
188
print(f"Waiting {wait_time} seconds before retry...")
189
time.sleep(wait_time)
190
else:
191
raise
192
193
except AppError as e:
194
print(f"Application error: {e.message}")
195
# Log error details
196
print(f"Title: {e.title}")
197
print(f"Duration: {e.duration}")
198
199
# Don't retry application errors - fix input instead
200
raise
201
202
except SerializationSetupError as e:
203
print(f"Serialization error: {e}")
204
# Don't retry serialization errors - fix data format
205
raise
206
207
except httpx.TimeoutException as e:
208
print(f"Timeout error (attempt {attempt + 1}/{max_retries}): {e}")
209
if attempt < max_retries - 1:
210
time.sleep(1)
211
else:
212
raise
213
214
except Exception as e:
215
print(f"Unexpected error (attempt {attempt + 1}/{max_retries}): {e}")
216
if attempt < max_retries - 1:
217
time.sleep(1)
218
else:
219
raise
220
221
# Usage
222
try:
223
result = robust_prediction("abidlabs/whisper", "audio.wav")
224
print(f"Success: {result}")
225
except Exception as e:
226
print(f"Final error: {e}")
227
```
228
229
### Job Error Handling
230
231
```python
232
from gradio_client import Client
233
from gradio_client.exceptions import AppError
234
import concurrent.futures
235
236
client = Client("abidlabs/batch-processor")
237
238
def process_with_timeout(input_data, timeout=30):
239
"""Process input with timeout and error handling."""
240
try:
241
job = client.submit(input_data, api_name="/process")
242
243
# Wait for result with timeout
244
result = job.result(timeout=timeout)
245
return {"success": True, "result": result, "error": None}
246
247
except TimeoutError:
248
# Try to cancel the job
249
cancelled = job.cancel()
250
return {
251
"success": False,
252
"result": None,
253
"error": f"Timeout after {timeout}s, cancelled: {cancelled}"
254
}
255
256
except AppError as e:
257
return {
258
"success": False,
259
"result": None,
260
"error": f"App error: {e.message}"
261
}
262
263
# Process multiple inputs
264
inputs = ["data1.csv", "data2.csv", "data3.csv"]
265
results = []
266
267
for input_data in inputs:
268
result = process_with_timeout(input_data, timeout=60)
269
results.append(result)
270
271
if not result["success"]:
272
print(f"Failed to process {input_data}: {result['error']}")
273
274
print(f"Successfully processed {sum(1 for r in results if r['success'])} out of {len(inputs)} items")
275
```
276
277
### Custom Error Context
278
279
```python
280
from gradio_client import Client
281
from gradio_client.exceptions import AppError
282
import logging
283
284
# Set up logging
285
logging.basicConfig(level=logging.INFO)
286
logger = logging.getLogger(__name__)
287
288
class GradioClientWrapper:
289
"""Wrapper with enhanced error handling and logging."""
290
291
def __init__(self, space_id: str, **kwargs):
292
self.space_id = space_id
293
try:
294
self.client = Client(space_id, **kwargs)
295
logger.info(f"Successfully connected to {space_id}")
296
except Exception as e:
297
logger.error(f"Failed to connect to {space_id}: {e}")
298
raise
299
300
def safe_predict(self, *args, **kwargs):
301
"""Make prediction with detailed error context."""
302
try:
303
logger.info(f"Making prediction with args: {args}")
304
result = self.client.predict(*args, **kwargs)
305
logger.info("Prediction successful")
306
return result
307
308
except AppError as e:
309
# Log application-specific errors with context
310
logger.error(f"Application error in {self.space_id}")
311
logger.error(f"Title: {e.title}")
312
logger.error(f"Message: {e.message}")
313
logger.error(f"Duration: {e.duration}")
314
315
# Create custom exception with more context
316
raise RuntimeError(
317
f"Prediction failed for Space '{self.space_id}': {e.message}"
318
) from e
319
320
except Exception as e:
321
logger.error(f"Unexpected error in {self.space_id}: {e}")
322
raise RuntimeError(
323
f"Unexpected error in Space '{self.space_id}': {str(e)}"
324
) from e
325
326
# Usage
327
try:
328
wrapper = GradioClientWrapper("abidlabs/whisper")
329
result = wrapper.safe_predict("audio.wav", api_name="/predict")
330
print(f"Transcription: {result}")
331
332
except RuntimeError as e:
333
print(f"Processing failed: {e}")
334
# Original exception is available as e.__cause__
335
```
336
337
### Graceful Degradation
338
339
```python
340
from gradio_client import Client
341
from gradio_client.exceptions import AuthenticationError, AppError
342
import warnings
343
344
def get_client_with_fallback(primary_space: str, fallback_space: str, hf_token: str | None = None):
345
"""Get client with fallback to alternative space."""
346
347
# Try primary space first
348
try:
349
client = Client(primary_space, hf_token=hf_token)
350
print(f"Connected to primary space: {primary_space}")
351
return client, primary_space
352
353
except AuthenticationError:
354
warnings.warn(f"Authentication failed for {primary_space}, trying fallback")
355
356
except Exception as e:
357
warnings.warn(f"Failed to connect to {primary_space}: {e}, trying fallback")
358
359
# Try fallback space
360
try:
361
client = Client(fallback_space, hf_token=hf_token)
362
print(f"Connected to fallback space: {fallback_space}")
363
return client, fallback_space
364
365
except Exception as e:
366
raise RuntimeError(f"Failed to connect to both {primary_space} and {fallback_space}") from e
367
368
def predict_with_fallback(primary_space: str, fallback_space: str, input_data, **kwargs):
369
"""Make prediction with automatic fallback."""
370
371
client, active_space = get_client_with_fallback(primary_space, fallback_space)
372
373
try:
374
result = client.predict(input_data, **kwargs)
375
return result, active_space
376
377
except AppError as e:
378
if active_space == primary_space:
379
warnings.warn(f"Primary space failed: {e.message}, trying fallback")
380
# Try fallback
381
try:
382
fallback_client = Client(fallback_space)
383
result = fallback_client.predict(input_data, **kwargs)
384
return result, fallback_space
385
except Exception as fallback_error:
386
raise RuntimeError(f"Both spaces failed. Primary: {e.message}, Fallback: {fallback_error}") from e
387
else:
388
# Already using fallback, reraise
389
raise
390
391
# Usage
392
try:
393
result, used_space = predict_with_fallback(
394
"user/private-whisper",
395
"abidlabs/whisper",
396
"audio.wav",
397
api_name="/predict"
398
)
399
print(f"Transcription from {used_space}: {result}")
400
401
except RuntimeError as e:
402
print(f"All options exhausted: {e}")
403
```