0
# Error Handling
1
2
Comprehensive HTTP exception hierarchy and error handling mechanisms for building robust APIs with proper status codes, error responses, and custom error processing.
3
4
## Capabilities
5
6
### Base Error Classes
7
8
Foundation classes for HTTP errors and status responses.
9
10
```python { .api }
11
class HTTPError(Exception):
12
def __init__(
13
self,
14
status: str,
15
title: str = None,
16
description: str = None,
17
headers: dict = None,
18
href: str = None,
19
href_text: str = None,
20
code: int = None
21
):
22
"""
23
Base HTTP error class.
24
25
Args:
26
status: HTTP status line (e.g., '400 Bad Request')
27
title: Error title for response
28
description: Detailed error description
29
headers: Additional response headers
30
href: URI for more information
31
href_text: Link text for href
32
code: Application-specific error code
33
"""
34
35
def to_dict(self) -> dict:
36
"""
37
Convert error to dictionary representation.
38
39
Returns:
40
Error as dictionary
41
"""
42
43
def to_json(self) -> str:
44
"""
45
Convert error to JSON string.
46
47
Returns:
48
Error as JSON
49
"""
50
51
# Properties
52
status: str # HTTP status line
53
title: str # Error title
54
description: str # Error description
55
headers: dict # Additional headers
56
href: str # Information URI
57
href_text: str # Link text
58
code: int # Error code
59
60
class HTTPStatus(Exception):
61
def __init__(self, status: str, headers: dict = None):
62
"""
63
HTTP status response without error body.
64
65
Args:
66
status: HTTP status line
67
headers: Additional response headers
68
"""
69
70
# Properties
71
status: str # HTTP status line
72
headers: dict # Response headers
73
```
74
75
#### Basic Error Usage
76
77
```python
78
import falcon
79
80
class UserResource:
81
def on_get(self, req, resp, user_id):
82
user = get_user(user_id)
83
if not user:
84
raise falcon.HTTPNotFound(
85
title='User not found',
86
description=f'User with ID {user_id} does not exist'
87
)
88
89
resp.media = user
90
91
def on_post(self, req, resp):
92
try:
93
user_data = req.media
94
validate_user_data(user_data)
95
new_user = create_user(user_data)
96
resp.status = falcon.HTTP_201
97
resp.media = new_user
98
except ValidationError as e:
99
raise falcon.HTTPBadRequest(
100
title='Invalid user data',
101
description=str(e),
102
code=40001 # Application-specific code
103
)
104
```
105
106
### 4xx Client Error Classes
107
108
HTTP client error exceptions for handling invalid requests.
109
110
```python { .api }
111
# 400 series errors
112
class HTTPBadRequest(HTTPError):
113
"""400 Bad Request"""
114
115
class HTTPUnauthorized(HTTPError):
116
"""401 Unauthorized"""
117
118
class HTTPForbidden(HTTPError):
119
"""403 Forbidden"""
120
121
class HTTPNotFound(HTTPError):
122
"""404 Not Found"""
123
124
class HTTPMethodNotAllowed(HTTPError):
125
"""405 Method Not Allowed"""
126
127
class HTTPNotAcceptable(HTTPError):
128
"""406 Not Acceptable"""
129
130
class HTTPConflict(HTTPError):
131
"""409 Conflict"""
132
133
class HTTPGone(HTTPError):
134
"""410 Gone"""
135
136
class HTTPLengthRequired(HTTPError):
137
"""411 Length Required"""
138
139
class HTTPPreconditionFailed(HTTPError):
140
"""412 Precondition Failed"""
141
142
class HTTPContentTooLarge(HTTPError):
143
"""413 Content Too Large"""
144
145
class HTTPPayloadTooLarge(HTTPError):
146
"""413 Payload Too Large (alias)"""
147
148
class HTTPUriTooLong(HTTPError):
149
"""414 URI Too Long"""
150
151
class HTTPUnsupportedMediaType(HTTPError):
152
"""415 Unsupported Media Type"""
153
154
class HTTPRangeNotSatisfiable(HTTPError):
155
"""416 Range Not Satisfiable"""
156
157
class HTTPUnprocessableEntity(HTTPError):
158
"""422 Unprocessable Entity"""
159
160
class HTTPLocked(HTTPError):
161
"""423 Locked"""
162
163
class HTTPFailedDependency(HTTPError):
164
"""424 Failed Dependency"""
165
166
class HTTPPreconditionRequired(HTTPError):
167
"""428 Precondition Required"""
168
169
class HTTPTooManyRequests(HTTPError):
170
"""429 Too Many Requests"""
171
172
class HTTPRequestHeaderFieldsTooLarge(HTTPError):
173
"""431 Request Header Fields Too Large"""
174
175
class HTTPUnavailableForLegalReasons(HTTPError):
176
"""451 Unavailable For Legal Reasons"""
177
```
178
179
### 5xx Server Error Classes
180
181
HTTP server error exceptions for handling internal errors.
182
183
```python { .api }
184
# 500 series errors
185
class HTTPInternalServerError(HTTPError):
186
"""500 Internal Server Error"""
187
188
class HTTPNotImplemented(HTTPError):
189
"""501 Not Implemented"""
190
191
class HTTPBadGateway(HTTPError):
192
"""502 Bad Gateway"""
193
194
class HTTPServiceUnavailable(HTTPError):
195
"""503 Service Unavailable"""
196
197
class HTTPGatewayTimeout(HTTPError):
198
"""504 Gateway Timeout"""
199
200
class HTTPVersionNotSupported(HTTPError):
201
"""505 HTTP Version Not Supported"""
202
203
class HTTPInsufficientStorage(HTTPError):
204
"""507 Insufficient Storage"""
205
206
class HTTPLoopDetected(HTTPError):
207
"""508 Loop Detected"""
208
209
class HTTPNetworkAuthenticationRequired(HTTPError):
210
"""511 Network Authentication Required"""
211
```
212
213
### Specialized Error Classes
214
215
Domain-specific error classes for common web application scenarios.
216
217
```python { .api }
218
# Route and routing errors
219
class HTTPRouteNotFound(HTTPNotFound):
220
"""Specific route not found error"""
221
222
# Header validation errors
223
class HTTPInvalidHeader(HTTPBadRequest):
224
"""Invalid header value error"""
225
226
class HTTPMissingHeader(HTTPBadRequest):
227
"""Required header missing error"""
228
229
# Parameter validation errors
230
class HTTPInvalidParam(HTTPBadRequest):
231
"""Invalid parameter value error"""
232
233
class HTTPMissingParam(HTTPBadRequest):
234
"""Required parameter missing error"""
235
236
# Media processing errors
237
class MediaNotFoundError(Exception):
238
"""Media handler not found"""
239
240
class MediaMalformedError(Exception):
241
"""Malformed media content"""
242
243
class MediaValidationError(Exception):
244
"""Media validation failed"""
245
246
class MultipartParseError(Exception):
247
"""Multipart form parsing error"""
248
249
# General application errors
250
class CompatibilityError(Exception):
251
"""Compatibility issue error"""
252
253
class HeaderNotSupported(Exception):
254
"""Unsupported header error"""
255
256
class InvalidMediaType(Exception):
257
"""Invalid media type error"""
258
259
class InvalidMediaRange(Exception):
260
"""Invalid media range error"""
261
262
class UnsupportedScopeError(Exception):
263
"""Unsupported ASGI scope error"""
264
265
class UnsupportedError(Exception):
266
"""General unsupported operation error"""
267
268
class OperationNotAllowed(Exception):
269
"""Operation not allowed error"""
270
271
class DelimiterError(Exception):
272
"""Delimiter parsing error"""
273
274
class PayloadTypeError(Exception):
275
"""Payload type error"""
276
```
277
278
### WebSocket Error Classes
279
280
Error classes specific to WebSocket handling in ASGI applications.
281
282
```python { .api }
283
# WebSocket errors
284
class WebSocketDisconnected(Exception):
285
"""WebSocket connection disconnected"""
286
287
class WebSocketPathNotFound(Exception):
288
"""WebSocket path not found"""
289
290
class WebSocketHandlerNotFound(Exception):
291
"""WebSocket handler not found"""
292
293
class WebSocketServerError(Exception):
294
"""WebSocket server error"""
295
```
296
297
### Redirect Classes
298
299
HTTP redirect responses for URL redirection.
300
301
```python { .api }
302
class HTTPMovedPermanently(HTTPStatus):
303
def __init__(self, location: str):
304
"""
305
301 Moved Permanently redirect.
306
307
Args:
308
location: New resource location
309
"""
310
311
class HTTPFound(HTTPStatus):
312
def __init__(self, location: str):
313
"""
314
302 Found redirect.
315
316
Args:
317
location: Temporary resource location
318
"""
319
320
class HTTPSeeOther(HTTPStatus):
321
def __init__(self, location: str):
322
"""
323
303 See Other redirect.
324
325
Args:
326
location: Alternative resource location
327
"""
328
329
class HTTPTemporaryRedirect(HTTPStatus):
330
def __init__(self, location: str):
331
"""
332
307 Temporary Redirect.
333
334
Args:
335
location: Temporary resource location
336
"""
337
338
class HTTPPermanentRedirect(HTTPStatus):
339
def __init__(self, location: str):
340
"""
341
308 Permanent Redirect.
342
343
Args:
344
location: New permanent resource location
345
"""
346
```
347
348
#### Redirect Usage Example
349
350
```python
351
class RedirectResource:
352
def on_get(self, req, resp):
353
# Permanent redirect to new URL
354
raise falcon.HTTPMovedPermanently('/new-location')
355
356
def on_post(self, req, resp):
357
# Process form and redirect to success page
358
process_form(req.media)
359
raise falcon.HTTPSeeOther('/success')
360
```
361
362
### Custom Error Handling
363
364
Advanced error handling with custom handlers and serializers.
365
366
```python { .api }
367
# Error handler function signature
368
def error_handler(req: Request, resp: Response, ex: Exception, params: dict):
369
"""
370
Custom error handler function.
371
372
Args:
373
req: Request object
374
resp: Response object
375
ex: Exception that occurred
376
params: Route parameters
377
"""
378
379
# Error serializer function signature
380
def error_serializer(req: Request, resp: Response, exception: HTTPError) -> object:
381
"""
382
Custom error serializer function.
383
384
Args:
385
req: Request object
386
resp: Response object
387
exception: HTTPError to serialize
388
389
Returns:
390
Serializable error representation
391
"""
392
```
393
394
#### Custom Error Handling Example
395
396
```python
397
import falcon
398
import logging
399
400
def database_error_handler(req, resp, ex, params):
401
"""Handle database connection errors"""
402
logging.error(f"Database error: {ex}")
403
404
resp.status = falcon.HTTP_503
405
resp.media = {
406
'error': 'Database temporarily unavailable',
407
'retry_after': 60
408
}
409
resp.set_header('Retry-After', '60')
410
411
def validation_error_handler(req, resp, ex, params):
412
"""Handle validation errors with detailed messages"""
413
resp.status = falcon.HTTP_400
414
resp.media = {
415
'error': 'Validation failed',
416
'details': ex.errors if hasattr(ex, 'errors') else str(ex),
417
'request_id': req.context.get('request_id')
418
}
419
420
def custom_error_serializer(req, resp, exception):
421
"""Custom JSON error format"""
422
return {
423
'success': False,
424
'error': {
425
'type': exception.__class__.__name__,
426
'title': exception.title,
427
'detail': exception.description,
428
'status': exception.status,
429
'timestamp': datetime.utcnow().isoformat()
430
}
431
}
432
433
# Register error handlers
434
app = falcon.App()
435
app.add_error_handler(DatabaseError, database_error_handler)
436
app.add_error_handler(ValidationError, validation_error_handler)
437
app.set_error_serializer(custom_error_serializer)
438
```
439
440
## Types
441
442
```python { .api }
443
# Error classes
444
HTTPError: type # Base HTTP error
445
HTTPStatus: type # Status-only response
446
447
# 4xx client errors
448
HTTPBadRequest: type
449
HTTPUnauthorized: type
450
HTTPForbidden: type
451
HTTPNotFound: type
452
# ... (all 4xx error classes)
453
454
# 5xx server errors
455
HTTPInternalServerError: type
456
HTTPServiceUnavailable: type
457
# ... (all 5xx error classes)
458
459
# Redirect classes
460
HTTPMovedPermanently: type
461
HTTPFound: type
462
HTTPSeeOther: type
463
HTTPTemporaryRedirect: type
464
HTTPPermanentRedirect: type
465
466
# Specialized errors
467
MediaNotFoundError: type
468
MultipartParseError: type
469
WebSocketDisconnected: type
470
# ... (all specialized error classes)
471
```