A abstract base class for exceptions
Project description
jr_exception_tools
Index
- Overview
- Features
- Notes
- Exception Message Example
- Installation
- Usage
- Exception Modes
- Custom Keys
- Signature
- Attributes
- Messages Modes
- Running the tests
- Contributing
- License
Overview
ExceptionBase is a customizable, structured exception-handling framework for Python. It provides enhanced error reporting, automatic context capture, rich formatting options, and seamless logging integration. The library is lightweight and optimized using caches for better performance and memory efficiency.
Features
-
Multiple Exception Formats: Supports simple, complex, traceback, and custom exception modes.
-
Automatic Context Capture: Extracts filename, function, line number, and more.
-
Rich Formatting: Supports JSON, rich table output, and structured logging.
-
Thread-Safe: Uses locking to ensure safe exception handling.
-
Exception Chaining: Easily tracks nested exceptions.
-
Lightweight: Requires minimal dependencies.
-
Logging Integration: Logs exceptions using the provided logger.
Notes
- The
ExceptionBaseclass is designed to be used as a base class for custom exceptions. - rich attribute will make a table with the exception details.
Exception Message Example
====== BookValidationException ======
Message: Error performing validation operation
Time Stamp: 2025-02-05 22:45:05
Filename: book_exceptions.py
Class: BookValidationException
Module: MyModule
Function: do_something
Line: 354
Exception: TypeError
Error Message: unsupported operand type(s) for +: 'int' and 'str'
Installation
Ensure rich and pytest(in case of testing) are installed:
pip install rich pytest
Then install the library:
pip install jr_exception_tools
Usage
Basic Exception Handling
from jr_exception_tools import ExceptionBase
# Define your custom exception class inheriting from ExceptionBase
class MyCustomException(ExceptionBase):
pass
try:
# Raise a error
raise ValueError("Invalid operation")
except ValueError as e:
# Raise your custom exception
raise MyCustomException(
message="A custom exception occurred",
exception=e,
mode="simple"
)
Filling all parameters
try:
raise RuntimeError("Runtime error")
except RuntimeError as e:
# You can fill all parameters with your own values
raise MyCustomException(
message="Detailed error report",
filename="my_file.py",
class_name="MyClass",
module_name="my_module",
function="my_function",
line=100,
exception=e,
mode="complex",
)
Automatic context capture
try:
raise RuntimeError("Runtime error")
except RuntimeError as e:
# Captures the source code information automatically
raise MyCustomException(
message="Detailed error report",
exception=e,
mode="complex",
)
Custom exception mode
try:
raise RuntimeError("Runtime error")
except RuntimeError as e:
# Custom exception will uses a list of keys
raise MyCustomException(
message="Detailed error report",
exception=e,
mode="custom",
list_of_keys=["time", "function", "line"],
# Time, Function, and Line will be displayed in the exception
)
Traceback mode
try:
raise RuntimeError("Runtime error")
except RuntimeError as e:
# Traceback mode will display the traceback
raise MyCustomException(
message="Detailed error report",
exception=e,
mode="traceback",
)
Logging Integration
logger = logging.getLogger("my_logger")
try:
raise ValueError("Something went wrong")
except ValueError as e:
raise ExceptionBase(
message="Error with logging",
exception=e,
mode="complex",
logger=logger # Will log the exception
)
Additional information
additional_info = {
"user": "John Doe",
"operation": "Operation 1",
}
try:
raise ValueError("Something went wrong")
except ValueError as e:
# Additional information will be displayed in the exception message
raise ExceptionBase(
message="Error with additional information",
exception=e,
additional_message=additional_info,
mode="complex",
)
Exception Modes
| Mode | Description |
|---|---|
| simple | Simple mode will display only the message and exception type. |
| complex | Complex mode will display the filename, message, class, module, function, and line number. Along with the exception type and error message. |
| traceback | Traceback mode will display the traceback. |
| custom | Custom mode will display the message and additional information. |
Custom Keys
- Set of keys to use as the
list_of_keysparameter for custom exception message.
raise MyCustomException(
message="Custom error report",
exception=e,
mode="custom",
list_of_keys=["time", "class" "function", "line"],
) # Time, Class, Function, and Line will be displayed in the exception
| Key | Description |
|---|---|
| time | The time the exception was raised. |
| filename | The filename where the exception was raised. |
| class | The class name where the exception was raised. |
| module | The module name where the exception was raised. |
| function | The function name where the exception was raised. |
| line | The line number where the exception was raised. |
Signature
def __init__(
self,
message: str | None = None,
additional_message: Dict[str, Any] | None = None,
filename: str | None = None,
class_name: str | None = None,
module_name: str | None = None,
function: str | None = None,
line: int | None = None,
exception: Exception | None = None,
mode: Literal["simple", "complex", "traceback", "custom"] = "simple",
list_of_keys: list[str] | None = None,
logger: Logger | None = None,
use_rich: bool = False,
json: bool = False,
) -> None:
Attributes
| Attribute | Type | Description |
|---|---|---|
| message | str | The message associated with the exception. |
| additional_message | Dict[str, Any] | The additional message associated with the exception. |
| filename | str | The filename associated with the exception. |
| class_name | str | The class name associated with the exception. |
| module_name | str | The module name associated with the exception. |
| function | str | The function name associated with the exception. |
| line | int | The line number associated with the exception. |
| exception | Exception | The exception associated with the exception. |
| mode | Literal["simple", "complex", "traceback", "custom"] | The mode associated with the exception. |
| list_of_keys | list[str] | The list of keys associated with the exception. |
| logger | Logger | The logger associated with the exception. |
| use_rich | bool | Whether to use rich formatting or not. |
| json | bool | Whether to return the additional message as a JSON string, as the sole output. |
Messages Modes
Simple:
try:
...
raise TypeError ("unsupported operand type(s) for +: 'int' and 'str'")
except TypeError as e:
raise BookValidationException(
message="Error performing validation operation",
exception=e,
mode="simple".
)
Output:
====== BookValidationException ======
Message: Error performing validation operation
Exception: TypeError
Error Message: unsupported operand type(s) for +: 'int' and 'str'
Complex:
try:
...
raise TypeError ("unsupported operand type(s) for +: 'int' and 'str'")
except TypeError as e:
raise BookValidationException(
message="Error performing validation operation",
exception=e,
mode="complex".
)
Output:
====== BookValidationException ======
Message: Error performing validation operation
Time Stamp: 2025-02-05 22:45:05
Filename: book_exceptions.py
Class: BookValidationException
Module: __main__
Function: do_something
Line: 354
Exception: TypeError
Error Message: unsupported operand type(s) for +: 'int' and 'str'
Custom:-> ["time","function", "line"]
try:
...
raise TypeError ("unsupported operand type(s) for +: 'int' and 'str'")
except TypeError as e:
raise BookValidationException(
message="Error performing validation operation",
exception=e,
mode="custom",
list_of_keys = ["time","function", "line"]
)
Output:
====== BookValidationException ======
Message: Error performing validation operation
Time Stamp: 2025-02-06 17:56:54
Function: do_something
Line: 745
Exception: TypeError
Error Message: unsupported operand type(s) for +: 'int' and 'str'
Additional Message:
try:
...
raise TypeError ("unsupported operand type(s) for +: 'int' and 'str'")
except TypeError as e:
raise BookValidationException(
message="Error performing validation operation",
exception=e,
mode="simple".
additional_message = {
"user" = "John Doe",
"Operation" = "Operation 1"
}
)
Output:
CBookSecurityException:
====== CBookSecurityException ======
Message: Security error occurred while performing operation
Exception: TypeError
Error Message: Some TypeError
====== Additional Information ======
user: John Doe
operation: Operation 1
Nested Exceptions:
CBookSecurityException:
====== CBookSecurityException ======
Message: Security error occurred while performing operation
Time Stamp: 2025-02-06 20:35:17
Filename: module_exceptions.py
Class: CBookSecurityException
Module: __main__
Function: do_something
Line: 783
====== Chain of Exceptions ======
CBookSecurityException -> BookValidationException
====== BookValidationException ======
Message: Error performing validation operation
Time Stamp: 2025-02-06 20:35:17
Filename: module_exceptions.py
Class: BookValidationException
Module: __main__
Function: do_something
Line: 781
Error Message: unsupported operand type(s) for +: 'int' and 'str'
Rich:
try:
...
raise TypeError ("unsupported operand type(s) for +: 'int' and 'str'")
except TypeError as e:
raise BookValidationException(
message="Error performing validation operation",
exception=e,
mode="simple",
use_rich= True
)
Output:
CBookSecurityException: CBookSecurityException
┏━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Key ┃ Value ┃
┡━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ message │ Security error occurred while performing operation │
│ exception │ BookValidationException │
│ error_message │ Error performing validation operation │
└───────────────┴────────────────────────────────────────────────────┘
Nested Rich:
CBookSecurityException: CBookSecurityException
┏━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Key ┃ Value ┃
┡━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ message │ Security error occurred while performing operation │
│ time │ 2025-02-06 20:34:30 │
│ filename │ module_exceptions.py │
│ class │ CBookSecurityException │
│ module │ __main__ │
│ function │ do_something │
│ line │ 783 │
│ chain_of_exceptions │ CBookSecurityException -> BookValidationException │
└─────────────────────┴────────────────────────────────────────────────────┘
BookValidationException
┏━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Key ┃ Value ┃
┡━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ message │ Error performing validation operation │
│ time │ 2025-02-06 20:34:30 │
│ filename │ module_exceptions.py │
│ class │ BookValidationException │
│ module │ __main__ │
│ function │ do_something │
│ line │ 781 │
│ exception │ TypeError │
│ error_message │ unsupported operand type(s) for +: 'int' and 'str' │
└───────────────┴────────────────────────────────────────────────────┘
Direct JSON Output:
try:
...
raise TypeError ("unsupported operand type(s) for +: 'int' and 'str'")
except TypeError as e:
raise BookValidationException(
additional_message= {
"message": "Security error occurred while performing operation",
"exception": "TypeError",
"error_message": "unsupported operand type(s) for +: 'int' and 'str'"
}
)
Output:
{
"message": "Security error occurred while performing operation",
"exception": "TypeError",
"error_message": "unsupported operand type(s) for +: 'int' and 'str'"
}
Make JSON message
- Get a JSON formatted message from the exception
try:
...
raise TypeError("unsupported operand type(s) for +: 'int' and 'str'")
except TypeError as e:
# Make JSON message
ex = MyCustomException(
message="Security error occurred while performing operation",
exception=e,
mode="complex",
)
print(ex._JSONMessage())
Output:
{
"message": "Security error occurred while performing operation",
"time": "2025-02-06 21:11:03",
"filename": "module_exceptions.py",
"class": "CBookSecurityException",
"module": "__main__",
"function": "do_something",
"line": 816,
"chain_of_exceptions": "CBookSecurityException -> BookValidationException",
"exception": "BookValidationException",
"exception_message": "Error performing validation operation",
"error_type": "TypeError",
"error_message": "unsupported operand type(s) for +: 'int' and 'str'"
}
Running the tests
To run the tests, you can use the following command:
pytest tests_exceptions.py
Contributing
Contributions are welcome! Feel free to submit issues or pull requests.
License
MIT License
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file jr_exception_tools-0.2.1.tar.gz.
File metadata
- Download URL: jr_exception_tools-0.2.1.tar.gz
- Upload date:
- Size: 16.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
26c21560b28858ecefcc42b9600dd378dbbb61e4fab62f85012ee07e0fc8bf2f
|
|
| MD5 |
7dedb1023d9722a0e24308259869c2be
|
|
| BLAKE2b-256 |
3c0b2060273a4bbca3b7216e972fef9b1fe8b4b7f390fb76cdd3f1729c9674c7
|
File details
Details for the file jr_exception_tools-0.2.1-py3-none-any.whl.
File metadata
- Download URL: jr_exception_tools-0.2.1-py3-none-any.whl
- Upload date:
- Size: 11.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ecffda7bbd15ed00f826b169d55121dbd4fde93e42f39e78eff469bce92acbc1
|
|
| MD5 |
821c188331e0ae4d63b3b67be434fa96
|
|
| BLAKE2b-256 |
eff8ff1de27bd829be6db5128bfaef96b8a1e72a95d5e892688350f8c6a83615
|