Skip to main content

A abstract base class for exceptions

Project description

jr_exception_tools


Index

  1. Overview
  2. Features
  3. Notes
  4. Exception Message Example
  5. Installation
  6. Usage
    1. Basic Exception Handling
    2. Filling all parameters
    3. Automatic context capture
    4. Custom exception mode
    5. Traceback mode
    6. Logging Integration
    7. Additional information
  7. Exception Modes
  8. Custom Keys
  9. Signature
  10. Attributes
  11. Messages Modes
  12. Running the tests
  13. Contributing
  14. 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 ExceptionBase class 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_keys parameter 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

jr_exception_tools-0.2.1.tar.gz (16.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

jr_exception_tools-0.2.1-py3-none-any.whl (11.7 kB view details)

Uploaded Python 3

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

Hashes for jr_exception_tools-0.2.1.tar.gz
Algorithm Hash digest
SHA256 26c21560b28858ecefcc42b9600dd378dbbb61e4fab62f85012ee07e0fc8bf2f
MD5 7dedb1023d9722a0e24308259869c2be
BLAKE2b-256 3c0b2060273a4bbca3b7216e972fef9b1fe8b4b7f390fb76cdd3f1729c9674c7

See more details on using hashes here.

File details

Details for the file jr_exception_tools-0.2.1-py3-none-any.whl.

File metadata

File hashes

Hashes for jr_exception_tools-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 ecffda7bbd15ed00f826b169d55121dbd4fde93e42f39e78eff469bce92acbc1
MD5 821c188331e0ae4d63b3b67be434fa96
BLAKE2b-256 eff8ff1de27bd829be6db5128bfaef96b8a1e72a95d5e892688350f8c6a83615

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page