finally clause executes regardless of whether exception occurred or was handled. Used for cleanup operations like closing files, database connections. Executes even if return, break, or continue occurs in try/except. Ensures resource cleanup.
Use logging module with different levels (DEBUG, INFO, WARNING, ERROR, CRITICAL). Configure handlers, formatters, log destinations. Example: logging.basicConfig(level=logging.INFO). Consider log rotation, timestamp formats, context information.
Group exceptions in tuple: except (TypeError, ValueError) as e. Access exception info using 'as' keyword. Consider exception hierarchy, order from specific to general. Handle each exception type appropriately.
Assertions (assert condition, message) check program correctness, disabled with -O flag. Exceptions handle runtime errors. Assertions for debugging/development, exceptions for runtime error handling. Use assertions for invariants.
Create decorators for timing, logging, error catching. Example: @log_errors, @retry, @timeout. Handle function metadata using functools.wraps. Consider performance impact, logging levels.
sys.excepthook handles uncaught exceptions. Customize for global error handling, logging. Access exception type, value, traceback. Consider different handling for different environments (dev/prod).
Implement consistent error response format, HTTP status codes. Include error codes, messages, debug information. Consider API versioning, client error handling. Example: {error: {code: 'VAL_001', message: 'Invalid input'}}.
Create wrapper classes/functions for error containment. Handle subsystem failures gracefully. Consider component isolation, fallback behavior. Example: class ErrorBoundary context manager.
pdb is Python's built-in debugger, ipdb adds IPython features like tab completion, syntax highlighting. Both support stepping through code, inspecting variables, setting breakpoints. Commands: n(next), s(step), c(continue), q(quit).
Basic structure uses try/except blocks: try to execute code that might raise exception, except to handle specific exceptions. Optional else clause for code when no exception occurs, finally for cleanup. Example: try: risky_operation() except TypeError: handle_error()
Use thread-specific exception handlers, threading.excepthook. Handle exceptions within thread function. Consider thread safety in logging, global error handlers. Implement proper thread cleanup.
Create base exception class for application. Structure hierarchy based on error types. Include relevant error information, maintain backwards compatibility. Example: AppError -> ValidationError -> FieldValidationError.
Use breakpoints, print debugging, sys.setrecursionlimit(). Monitor stack traces, memory usage. Tools: pdb for stepping through code. Implement timeout mechanisms, recursion depth checking.
Include specific error details, context information. Make messages user-friendly, actionable. Consider internationalization, security implications. Example: 'Failed to connect to database at host:port: timeout after 30s'.
Use source-level debugging, monkey patching. Inspect library source, logging integration. Consider version compatibility, issue tracking. Tools: debugger step-into, logging interception.
Implement specific exception handling for DB errors. Handle connection issues, transaction rollback. Consider retry logic, connection pooling. Example: handle SQLAlchemy exceptions specifically.
Create custom exceptions by inheriting from Exception class or specific exception types. Raise using raise keyword. Include meaningful error messages and attributes. Example: class CustomError(Exception): pass; raise CustomError('message')
Context managers (with statement) ensure proper resource cleanup. Implement __enter__ and __exit__ methods or use contextlib.contextmanager. Handle exceptions in __exit__. Example: file handling, database connections.
Use memory_profiler, tracemalloc, gc module. Monitor object references, circular references. Tools: objgraph for visualization, sys.getsizeof() for object size. Consider weak references, proper cleanup in __del__.
Use decorators or context managers for retries. Handle specific exceptions, implement backoff strategy. Example: @retry(times=3, exceptions=(NetworkError,)). Consider timeout, max attempts, delay between retries.
Use profilers (cProfile, line_profiler), timing decorators. Monitor CPU usage, memory allocation. Tools: py-spy for sampling profiler. Consider bottlenecks, optimization opportunities.
Use memory_profiler, guppy3 for heap analysis. Monitor object lifecycle, memory patterns. Consider garbage collection timing, object pooling. Tools: objgraph for reference visualization.