|
| 1 | +""" |
| 2 | +This example set demonstrates the use of the handle_errors context manager. |
| 3 | +The handle_errors context manager effectively wraps a block of code with |
| 4 | +a try-except without having to explicitly declare them. Additionally, it wraps |
| 5 | +all caught exceptions from the block in custom error messages |
| 6 | +""" |
| 7 | +from __future__ import annotations |
| 8 | + |
| 9 | +from typing import Any |
| 10 | + |
| 11 | +from buzz import handle_errors, DoExceptParams |
| 12 | + |
| 13 | + |
| 14 | +def simple_handle_errors(): |
| 15 | + """ |
| 16 | + This function demonstrates the simplest use of the handle_errors ctx_mgr. |
| 17 | + Note how the nested exception type is ValueError. The error produced by |
| 18 | + the handle_errors context manager should be of type HandleError. The |
| 19 | + resulting exception message will include the message supplied to the |
| 20 | + handle_error context manager as well as the message of the nested exception |
| 21 | + """ |
| 22 | + with handle_errors("something went wrong (simple example)"): |
| 23 | + print("here we are fine") |
| 24 | + raise ValueError("here we die") |
| 25 | + print("we should not get here") # pyright: ignore[reportUnreachable] |
| 26 | + |
| 27 | + |
| 28 | +def absorbing_handle_errors(): |
| 29 | + """ |
| 30 | + This function demonstrates a more complex usage of the handle_errors |
| 31 | + context manager where exceptions are absorbed. The following features |
| 32 | + are demonstrated: |
| 33 | +
|
| 34 | + * Handling a specific exception type with `exception_class` |
| 35 | + * Absorbing exceptions by setting `raise_exc_class` to `None` |
| 36 | + * Branching with `do_except`, `do_else`, and `do_finally` |
| 37 | + """ |
| 38 | + def _handler_function(dep: DoExceptParams): |
| 39 | + """ |
| 40 | + This function is a helper function for handling an exception from |
| 41 | + the handle_errors ctx_mgr. |
| 42 | + """ |
| 43 | + print(f"do_except() was called!") |
| 44 | + print(f"Handling exception: {dep.err}") |
| 45 | + print(f"Final Message: {dep.final_message}") |
| 46 | + |
| 47 | + with handle_errors( |
| 48 | + f"something went wrong (complex example)", |
| 49 | + raise_exc_class=None, |
| 50 | + do_except=_handler_function, |
| 51 | + do_else=lambda: print('do_else() was called!'), |
| 52 | + do_finally=lambda: print('do_finally() was called!'), |
| 53 | + ): |
| 54 | + print("here we are fine") |
| 55 | + raise ValueError("here we die") |
| 56 | + print("we should not get here") # pyright: ignore[reportUnreachable] |
| 57 | + |
| 58 | + |
| 59 | +def multiple_handle_errors(): |
| 60 | + """ |
| 61 | + This function demonstrates handling more than one exception type with the |
| 62 | + handle_errors context manager. The following features are demonstrated: |
| 63 | +
|
| 64 | + * Handling multiple exception types |
| 65 | +
|
| 66 | + Note that the final `TypeError` is _not_ handled! |
| 67 | + """ |
| 68 | + def _handler_function(dep: DoExceptParams): |
| 69 | + """ |
| 70 | + This function is a helper function for handling an exception from |
| 71 | + the handle_errors context manager. |
| 72 | + """ |
| 73 | + print(f"Handling exception type {dep.err.__class__}: {dep.final_message}") |
| 74 | + |
| 75 | + for exception_class in (ValueError, RuntimeError, AttributeError, TypeError): |
| 76 | + with handle_errors( |
| 77 | + f"something went wrong (multiple example)", |
| 78 | + handle_exc_class=(ValueError, RuntimeError, AttributeError), |
| 79 | + do_except=_handler_function, |
| 80 | + raise_exc_class=None, |
| 81 | + ): |
| 82 | + print("here we are fine") |
| 83 | + raise exception_class("here we die") |
| 84 | + print("we should not get here") # pyright: ignore[reportUnreachable] |
| 85 | + |
| 86 | + |
| 87 | +def specific_handle_errors(): |
| 88 | + """ |
| 89 | + This function demonstrates how handle_errors can be used to raise a specific |
| 90 | + exception type that wraps the error message of the handled exception. The |
| 91 | + following features are demonstrated: |
| 92 | +
|
| 93 | + * Raising a specific exception instance using the `raise_exc_class` parameter |
| 94 | + * Passing along ``raise_args` and `raise_kwargs` when raising the exception |
| 95 | + """ |
| 96 | + class DerivedError(Exception): |
| 97 | + |
| 98 | + def __init__(self, message: str, init_arg: Any, init_kwarg: Any | None = None): |
| 99 | + super().__init__(message) |
| 100 | + print(f"Derived Error initialized with: {init_arg=}, {init_kwarg=}") |
| 101 | + |
| 102 | + with handle_errors( |
| 103 | + f"something went wrong (specific example)", |
| 104 | + raise_exc_class=DerivedError, |
| 105 | + raise_args=["init arg"], |
| 106 | + raise_kwargs=dict(init_kwarg="init kwarg"), |
| 107 | + ): |
| 108 | + print("here we are fine") |
| 109 | + raise ValueError("here we die") |
| 110 | + print("we should not get here") # pyright: ignore[reportUnreachable] |
0 commit comments