.. module:: Exceptions Exceptions ========================= Utilities for extracting and handling structured exception information. Overview -------------------------- The exceptions module provides tools to capture detailed exception information in a structured format, making it easier to: - Log exceptions with full context - Serialize exception data for APIs - Debug production issues with complete stack traces - Monitor and track errors systematically Quick Examples -------------------------- Basic Exception Handling ~~~~~~~~~~~~~~~~~~~~~~~~~ Extract exception information during error handling: .. code-block:: python from core_mixins.exceptions import get_exception_data try: result = 10 / 0 except ZeroDivisionError: exc_type, exc_message, stack_trace = get_exception_data() print(f"Exception Type: {exc_type}") # "ZeroDivisionError" print(f"Message: {exc_message}") # "division by zero" print(f"Stack Depth: {len(stack_trace)}") # Number of frames Logging with Full Context ~~~~~~~~~~~~~~~~~~~~~~~~~~ Capture complete error information for logging: .. code-block:: python import logging from core_mixins.exceptions import get_exception_data logger = logging.getLogger(__name__) def process_data(data): try: # Process data result = data['value'] / data['divisor'] return result except Exception: exc_type, exc_message, stack_trace = get_exception_data() logger.error( f"Error processing data: {exc_type} - {exc_message}", extra={ "exception_type": exc_type, "exception_message": exc_message, "stack_trace": stack_trace } ) raise API Error Responses ~~~~~~~~~~~~~~~~~~~ Return structured error information in API responses: .. code-block:: python from flask import jsonify from core_mixins.exceptions import get_exception_data @app.route('/api/calculate', methods=['POST']) def calculate(): try: data = request.get_json() result = perform_calculation(data) return jsonify({"result": result}) except Exception: exc_type, exc_message, stack_trace = get_exception_data() return jsonify({ "error": { "type": exc_type, "message": exc_message, "stack_trace": stack_trace if app.debug else None } }), 500 Detailed Stack Trace Analysis ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Examine each frame in the stack trace: .. code-block:: python from core_mixins.exceptions import get_exception_data def divide_numbers(a, b): return a / b def calculate(): return divide_numbers(10, 0) try: calculate() except Exception: exc_type, exc_message, stack_trace = get_exception_data() print(f"\nException: {exc_type} - {exc_message}\n") print("Stack Trace:") for frame in stack_trace: print(f" File: {frame['File']}") print(f" Line: {frame['Line Number']} - {frame['Line']}") print(f" Function: {frame['Function']}") print() # Output: # Exception: ZeroDivisionError - division by zero # # Stack Trace: # File: /path/to/script.py # Line: 7 - return divide_numbers(10, 0) # Function: calculate # # File: /path/to/script.py # Line: 4 - return a / b # Function: divide_numbers Error Monitoring System ~~~~~~~~~~~~~~~~~~~~~~~ Build an error tracking system: .. code-block:: python from datetime import datetime from core_mixins.exceptions import get_exception_data import json class ErrorTracker: """Track and store application errors.""" def __init__(self): self.errors = [] def capture_exception(self, context=None): """Capture current exception with context.""" exc_type, exc_message, stack_trace = get_exception_data() error_record = { "timestamp": datetime.utcnow().isoformat(), "type": exc_type, "message": exc_message, "stack_trace": stack_trace, "context": context or {} } self.errors.append(error_record) return error_record def export_errors(self, filepath): """Export errors to JSON file.""" with open(filepath, 'w') as f: json.dump(self.errors, f, indent=2) # Usage tracker = ErrorTracker() try: # Application code process_user_data(user_id=123) except Exception: tracker.capture_exception(context={"user_id": 123}) raise Return Value Structure -------------------------- The ``get_exception_data()`` function returns a tuple with three elements: .. code-block:: python exc_type, exc_message, stack_trace = get_exception_data() **1. Exception Type (str)** The name of the exception class: .. code-block:: python "ZeroDivisionError" "KeyError" "ValueError" "FileNotFoundError" "Unknown" # When no exception info available **2. Exception Message (str)** The exception message describing what went wrong: .. code-block:: python "division by zero" "'missing_key'" "invalid literal for int() with base 10: 'abc'" "No such file or directory: 'data.txt'" **3. Stack Trace (List[Dict])** A list of dictionaries, each representing a stack frame: .. code-block:: python [ { "File": "/path/to/module.py", "Line Number": 42, "Line": "result = calculate(value)", "Function": "process_data" }, { "File": "/path/to/helpers.py", "Line Number": 15, "Line": "return numerator / denominator", "Function": "calculate" } ] Use Cases -------------------------- Error Logging and Monitoring ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Capture detailed error information for debugging: - Log structured exception data to monitoring systems (Sentry, DataDog, etc.) - Track error patterns and frequencies - Include stack traces in error reports API Error Handling ~~~~~~~~~~~~~~~~~~ Return consistent error responses: - Standardize error response format - Include stack traces in development mode - Hide sensitive information in production Debugging and Testing ~~~~~~~~~~~~~~~~~~~~~ Analyze exception context: - Examine the call stack to find error origins - Test error handling paths - Validate exception information in tests Error Recovery ~~~~~~~~~~~~~~ Make informed decisions based on exception details: .. code-block:: python try: perform_operation() except Exception: exc_type, exc_message, stack_trace = get_exception_data() # Retry for specific errors if exc_type in ("ConnectionError", "TimeoutError"): retry_operation() # Fail fast for others else: send_alert(exc_type, exc_message, stack_trace) raise Best Practices -------------------------- Always Call Within Exception Handler ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``get_exception_data()`` must be called inside an exception handler: .. code-block:: python # ✓ Correct try: risky_operation() except Exception: exc_type, exc_message, stack_trace = get_exception_data() # ✗ Wrong - No exception information available exc_type, exc_message, stack_trace = get_exception_data() Store or Log Immediately ~~~~~~~~~~~~~~~~~~~~~~~~~ Exception information is only available within the except block: .. code-block:: python # ✓ Correct - Store data immediately try: operation() except Exception: error_data = get_exception_data() # error_data can be used later # ✗ Wrong - Information lost after except block try: operation() except Exception: pass error_data = get_exception_data() # Returns empty/unknown Don't Expose Stack Traces in Production ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Filter sensitive information before sending to clients: .. code-block:: python import os try: process_request() except Exception: exc_type, exc_message, stack_trace = get_exception_data() # Include stack trace only in development response = { "error": exc_type, "message": exc_message } if os.getenv("ENV") == "development": response["stack_trace"] = stack_trace API Reference -------------------------- .. automodule:: core_mixins.exceptions :members: :undoc-members: :show-inheritance: