rspec/rules/S112/python/rule.adoc

68 lines
2.7 KiB
Plaintext

This rule raises an issue when a generic exception (such as `Exception` or `BaseException`) is raised.
== Why is this an issue?
Raising instances of https://docs.python.org/3/library/exceptions.html#Exception[``++Exception++``] and https://docs.python.org/3/library/exceptions.html#BaseException[``++BaseException++``] will have a negative impact on any code trying to catch these exceptions.
From a consumer perspective, it is generally a best practice to only catch exceptions you intend to handle. Other exceptions should ideally not be caught and let to propagate up the stack trace so that they can be dealt with appropriately. When a generic exception is thrown, it forces consumers to catch exceptions they do not intend to handle, which they then have to re-raise.
Besides, when working with a generic type of exception, the only way to distinguish between multiple exceptions is to check their message, which is error-prone and difficult to maintain. Legitimate exceptions may be unintentionally silenced and errors may be hidden.
For instance, if an exception such as `SystemExit` is caught and not re-raised, it will prevent the program from stopping.
When raising an exception, it is therefore recommended to raising the most specific exception possible so that it can be handled intentionally by consumers.
== How to fix it
To fix this issue, make sure to throw specific exceptions that are relevant to the context in which they arise. It is recommended to either:
* Raise a specific https://docs.python.org/3/library/exceptions.html[Built-in exception] when one matches. For example ``++TypeError++`` should be raised when the type of a parameter is not the one expected.
* Create a custom exception class deriving from ``++Exception++`` or one of its subclasses.
=== Code examples
==== Noncompliant code example
[source,python,diff-id=1,diff-type=noncompliant]
----
def check_value(value):
if value < 0:
raise BaseException("Value cannot be negative") # Noncompliant: this will be difficult for consumers to handle
----
==== Compliant solution
[source,python,diff-id=1,diff-type=compliant]
----
def check_value(value):
if value < 0:
raise ValueError("Value cannot be negative") # Compliant
----
== Resources
=== Documentation
* Python Documentation - https://docs.python.org/3/library/exceptions.html#BaseException[Built-in exceptions]
* PEP 352 - https://www.python.org/dev/peps/pep-0352/#exception-hierarchy-changes[Required Superclass for Exceptions]
ifdef::env-github,rspecator-view[]
'''
== Implementation Specification
(visible only on this page)
=== Message
Replace this generic exception class with a more specific one.
=== Highlighting
The "Exception" or "BaseException" class instantiation
'''
endif::env-github,rspecator-view[]