Skip to content

Commit 0abae5e

Browse files
[DOCUMENTATION] Apply suggestions from code review (- WIP #117 -)
1 parent 7caf930 commit 0abae5e

File tree

1 file changed

+70
-0
lines changed

1 file changed

+70
-0
lines changed

multicast/exceptions.py

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,13 +239,83 @@ def __init__(self, *args, **kwargs):
239239

240240

241241
def get_exit_code_from_exception(exc):
242+
"""
243+
Retrieve the exit code associated with a specific exception.
244+
245+
Parameters:
246+
exc (BaseException): The exception instance from which to retrieve the exit code.
247+
248+
Returns:
249+
int: The exit code corresponding to the given exception.
250+
251+
Raises:
252+
TypeError: If the provided argument is not an instance of BaseException.
253+
254+
Meta-Testing:
255+
256+
Testcase 1: Exception with a mapped exit code.
257+
>>> exc = FileNotFoundError('No such file or directory')
258+
>>> get_exit_code_from_exception(exc)
259+
66 # Exit code for FileNotFoundError
260+
261+
Testcase 2: Exception without a specific exit code.
262+
>>> exc = Exception('Generic error')
263+
>>> get_exit_code_from_exception(exc)
264+
70 # Default exit code for internal software error
265+
266+
"""
242267
for exc_class in EXCEPTION_EXIT_CODES:
243268
if isinstance(exc, exc_class):
244269
return EXCEPTION_EXIT_CODES[exc_class]
245270
return 70 # Default to 'Internal Software Error'
246271

247272

248273
def exit_on_exception(func):
274+
"""
275+
Decorator that wraps a function to handle exceptions and exit with appropriate exit codes.
276+
277+
This decorator captures exceptions raised by the wrapped function and handles them by mapping them to predefined exit codes specified in `EXIT_CODES`. It ensures that both `SystemExit` exceptions (which may be raised by modules like `argparse`) and other base exceptions result in the program exiting with meaningful exit codes and error messages.
278+
279+
Parameters:
280+
func (callable): The function to be wrapped by the decorator.
281+
282+
Returns:
283+
callable: The wrapped function with enhanced exception handling.
284+
285+
Meta-Testing:
286+
287+
Testcase 1: Successful execution without exceptions.
288+
A. Define a function that returns a value.
289+
B. Decorate it with `@exit_on_exception`.
290+
C. Call the function and confirm it returns the expected value.
291+
292+
>>> @exit_on_exception
293+
... def sample_func():
294+
... return "Success"
295+
>>> sample_func()
296+
'Success'
297+
298+
Testcase 2: Function raises `SystemExit` exception.
299+
A. Define a function that raises `SystemExit`.
300+
B. Decorate it with `@exit_on_exception`.
301+
C. Call the function and verify it exits with the correct exit code.
302+
303+
>>> @exit_on_exception
304+
... def system_exit_func():
305+
... raise SystemExit(64)
306+
>>> system_exit_func() # Exits with code 64
307+
308+
Testcase 3: Function raises a general exception.
309+
A. Define a function that raises a `ValueError`.
310+
B. Decorate it with `@exit_on_exception`.
311+
C. Call the function and verify it exits with the mapped exit code.
312+
313+
>>> @exit_on_exception
314+
... def error_func():
315+
... raise ValueError("Invalid value")
316+
>>> error_func() # Exits with code 65
317+
318+
"""
249319
def wrapper(*args, **kwargs):
250320
try:
251321
return func(*args, **kwargs)

0 commit comments

Comments
 (0)