CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-bravado

Library for accessing Swagger-enabled APIs

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

exception-handling.mddocs/

Exception Handling

Complete HTTP status code exception hierarchy with timeout and connection error handling. Bravado provides specific exceptions for all HTTP status codes plus bravado-specific errors, enabling precise error handling for robust applications.

Capabilities

HTTPError (Base Exception)

Unified HTTP error base class that all HTTP-related exceptions inherit from. Contains response data and optional swagger result.

class HTTPError(IOError):
    status_code: int
    def __init__(self, response, message: str = None, swagger_result=None): ...
    def __str__(self) -> str: ...

Attributes:

  • status_code (int): HTTP status code associated with this exception type
  • response: IncomingResponse object containing the HTTP response details
  • message (str): Optional custom error message
  • swagger_result: Parsed response data if available

Usage Example:

from bravado.exception import HTTPError, HTTPNotFound

try:
    pet = client.pet.getPetById(petId=999).response().result
except HTTPNotFound as e:
    print(f"Pet not found: {e}")
    print(f"Status code: {e.status_code}")
    print(f"Response body: {e.response.text}")
except HTTPError as e:
    print(f"HTTP error {e.status_code}: {e}")

Exception Hierarchy

Bravado organizes HTTP exceptions into logical categories:

HTTPRedirection (3xx)

Base class for 3xx redirection responses.

class HTTPRedirection(HTTPError): ...

Specific 3xx Exceptions:

  • HTTPMultipleChoices (300)
  • HTTPMovedPermanently (301)
  • HTTPFound (302)
  • HTTPSeeOther (303)
  • HTTPNotModified (304)
  • HTTPUseProxy (305)
  • HTTPTemporaryRedirect (307)
  • HTTPPermanentRedirect (308)

HTTPClientError (4xx)

Base class for 4xx client error responses.

class HTTPClientError(HTTPError): ...

Common 4xx Exceptions:

  • HTTPBadRequest (400) - Invalid request syntax or parameters
  • HTTPUnauthorized (401) - Authentication required or failed
  • HTTPPaymentRequired (402) - Payment required
  • HTTPForbidden (403) - Access denied
  • HTTPNotFound (404) - Resource not found
  • HTTPMethodNotAllowed (405) - HTTP method not supported
  • HTTPNotAcceptable (406) - Cannot produce acceptable response
  • HTTPRequestTimeout (408) - Request timeout
  • HTTPConflict (409) - Request conflicts with current state
  • HTTPGone (410) - Resource permanently removed
  • HTTPUnprocessableEntity (422) - Validation errors
  • HTTPTooManyRequests (429) - Rate limit exceeded

All 4xx Exceptions:

class HTTPBadRequest(HTTPClientError): status_code = 400
class HTTPUnauthorized(HTTPClientError): status_code = 401
class HTTPPaymentRequired(HTTPClientError): status_code = 402
class HTTPForbidden(HTTPClientError): status_code = 403
class HTTPNotFound(HTTPClientError): status_code = 404
class HTTPMethodNotAllowed(HTTPClientError): status_code = 405
class HTTPNotAcceptable(HTTPClientError): status_code = 406
class HTTPProxyAuthenticationRequired(HTTPClientError): status_code = 407
class HTTPRequestTimeout(HTTPClientError): status_code = 408
class HTTPConflict(HTTPClientError): status_code = 409
class HTTPGone(HTTPClientError): status_code = 410
class HTTPLengthRequired(HTTPClientError): status_code = 411
class HTTPPreconditionFailed(HTTPClientError): status_code = 412
class HTTPPayloadTooLarge(HTTPClientError): status_code = 413
class HTTPURITooLong(HTTPClientError): status_code = 414
class HTTPUnsupportedMediaType(HTTPClientError): status_code = 415
class HTTPRangeNotSatisfiable(HTTPClientError): status_code = 416
class HTTPExpectationFailed(HTTPClientError): status_code = 417
class HTTPMisdirectedRequest(HTTPClientError): status_code = 421
class HTTPUnprocessableEntity(HTTPClientError): status_code = 422
class HTTPLocked(HTTPClientError): status_code = 423
class HTTPFailedDependency(HTTPClientError): status_code = 424
class HTTPUpgradeRequired(HTTPClientError): status_code = 426
class HTTPPreconditionRequired(HTTPClientError): status_code = 428
class HTTPTooManyRequests(HTTPClientError): status_code = 429
class HTTPRequestHeaderFieldsTooLarge(HTTPClientError): status_code = 431
class HTTPUnavailableForLegalReasons(HTTPClientError): status_code = 451

HTTPServerError (5xx)

Base class for 5xx server error responses. Includes response text in string representation for debugging.

class HTTPServerError(HTTPError): ...

Common 5xx Exceptions:

  • HTTPInternalServerError (500) - Server internal error
  • HTTPNotImplemented (501) - Server does not support functionality
  • HTTPBadGateway (502) - Invalid response from upstream server
  • HTTPServiceUnavailable (503) - Server temporarily unavailable
  • HTTPGatewayTimeout (504) - Upstream server timeout
  • HTTPHTTPVersionNotSupported (505) - HTTP version not supported

All 5xx Exceptions:

class HTTPInternalServerError(HTTPServerError): status_code = 500
class HTTPNotImplemented(HTTPServerError): status_code = 501
class HTTPBadGateway(HTTPServerError): status_code = 502
class HTTPServiceUnavailable(HTTPServerError): status_code = 503
class HTTPGatewayTimeout(HTTPServerError): status_code = 504
class HTTPHTTPVersionNotSupported(HTTPServerError): status_code = 505
class HTTPVariantAlsoNegotiates(HTTPServerError): status_code = 506
class HTTPInsufficientStorage(HTTPServerError): status_code = 507
class HTTPLoopDetected(HTTPServerError): status_code = 508  
class HTTPNotExtended(HTTPServerError): status_code = 510
class HTTPNetworkAuthenticationRequired(HTTPServerError): status_code = 511

Connection and Transport Errors

Bravado-specific exceptions for connection and transport-level issues.

class BravadoTimeoutError(TimeoutError): ...
class BravadoConnectionError(ConnectionError): ...
class ForcedFallbackResultError(Exception): ...

BravadoTimeoutError: Raised when requests exceed configured timeout values. BravadoConnectionError: Raised when connection to the server cannot be established. ForcedFallbackResultError: Used internally to force fallback result behavior.

Exception Factory Function

Utility function to create appropriate HTTP exceptions from responses.

def make_http_exception(response, message: str = None, swagger_result=None) -> HTTPError: ...

Parameters:

  • response: IncomingResponse object
  • message (str): Optional custom error message
  • swagger_result: Parsed response data if available

Returns:

  • Appropriate HTTPError subclass instance based on status code

Usage Example:

from bravado.exception import make_http_exception

# Manually create exception from response
try:
    # ... some HTTP operation
    pass
except Exception as e:
    if hasattr(e, 'response'):
        http_exception = make_http_exception(e.response, "Custom error message")
        raise http_exception

Status Code Mapping

All HTTP status codes are mapped to their corresponding exception classes:

status_map: dict  # Mapping of int status codes to exception classes

This dictionary maps HTTP status codes to their corresponding exception classes and is used internally by the exception factory.

Error Handling Patterns

Basic Exception Handling

from bravado.exception import HTTPClientError, HTTPServerError, BravadoTimeoutError

try:
    response = client.pet.getPetById(petId=1).response()
    pet = response.result
except HTTPClientError as e:
    if e.status_code == 404:
        print("Pet not found")
    elif e.status_code == 401:
        print("Authentication required")
    else:
        print(f"Client error: {e.status_code}")
except HTTPServerError as e:
    print(f"Server error: {e.status_code}")
    print(f"Response: {e.response.text}")
except BravadoTimeoutError:
    print("Request timed out")

Specific Status Code Handling

from bravado.exception import HTTPNotFound, HTTPUnauthorized, HTTPTooManyRequests
import time

try:
    response = client.pet.getPetById(petId=1).response()
    pet = response.result
except HTTPNotFound:
    print("Pet does not exist")
    pet = None
except HTTPUnauthorized:
    print("Need to refresh authentication")
    # Handle re-authentication
except HTTPTooManyRequests as e:
    # Handle rate limiting
    retry_after = int(e.response.headers.get('Retry-After', 60))
    print(f"Rate limited, waiting {retry_after} seconds")
    time.sleep(retry_after)
    # Retry logic here

Validation Error Handling

from bravado.exception import HTTPBadRequest, HTTPUnprocessableEntity

try:
    response = client.pet.addPet(body=new_pet_data).response()
    pet = response.result
except HTTPBadRequest as e:
    print("Invalid request format")
    print(f"Error details: {e.response.text}")
except HTTPUnprocessableEntity as e:
    print("Validation failed")
    # Parse validation errors from response
    errors = e.response.json().get('errors', [])
    for error in errors:
        print(f"Field {error['field']}: {error['message']}")

Fallback with Exception Handling

from bravado.exception import HTTPServerError, BravadoTimeoutError

# Combine fallback results with specific exception handling
try:
    response = client.pet.getPetById(petId=1).response(
        timeout=5.0,
        fallback_result={'name': 'Unknown', 'status': 'unavailable'},
        exceptions_to_catch=(BravadoTimeoutError, HTTPServerError)
    )
    
    if response.metadata.is_fallback_result:
        print("Using fallback data due to service issues")
        # Handle degraded functionality
    
    pet = response.result
    
except HTTPNotFound:
    # Still handle specific client errors that shouldn't use fallback
    print("Pet definitely does not exist")
    pet = None

Logging and Monitoring

import logging
from bravado.exception import HTTPError

logger = logging.getLogger(__name__)

try:
    response = client.pet.getPetById(petId=1).response()
    pet = response.result
except HTTPError as e:
    # Log detailed error information for monitoring
    logger.error(
        "HTTP error in getPetById",
        extra={
            'status_code': e.status_code,
            'pet_id': 1,
            'response_body': e.response.text[:1000],  # Truncate for logging
            'response_headers': dict(e.response.headers),
        }
    )
    raise  # Re-raise for upstream handling

Best Practices

  1. Catch Specific Exceptions: Use specific exception types rather than generic HTTPError when possible
  2. Handle Expected Errors: Plan for common API errors like 404, 401, 429
  3. Log Error Details: Include status codes, response bodies, and request context in logs
  4. Use Fallback Results: Consider fallback results for non-critical operations
  5. Retry Logic: Implement appropriate retry logic for transient errors (5xx, timeouts)
  6. Rate Limiting: Respect rate limit headers and implement backoff strategies
# Good exception handling example
from bravado.exception import (
    HTTPNotFound, HTTPUnauthorized, HTTPTooManyRequests, 
    HTTPServerError, BravadoTimeoutError
)
import time
import random

def get_pet_with_retry(client, pet_id, max_retries=3):
    for attempt in range(max_retries + 1):
        try:
            response = client.pet.getPetById(petId=pet_id).response(timeout=10.0)
            return response.result
            
        except HTTPNotFound:
            return None  # Pet doesn't exist, don't retry
            
        except HTTPUnauthorized:
            # Handle re-authentication
            refresh_auth(client)
            continue
            
        except HTTPTooManyRequests as e:
            if attempt < max_retries:
                # Exponential backoff with jitter
                delay = (2 ** attempt) + random.uniform(0, 1)
                time.sleep(delay)
                continue
            raise
            
        except (HTTPServerError, BravadoTimeoutError) as e:
            if attempt < max_retries:
                # Retry transient errors
                delay = (2 ** attempt) + random.uniform(0, 1)
                time.sleep(delay)
                continue
            raise
    
    raise Exception(f"Failed to get pet {pet_id} after {max_retries} retries")

Install with Tessl CLI

npx tessl i tessl/pypi-bravado

docs

authentication.md

client-management.md

configuration.md

exception-handling.md

http-clients.md

index.md

response-handling.md

spec-loading.md

testing-utilities.md

tile.json