== Why is this an issue?

https://docs.python.org/3/library/exceptions.html#SystemExit[``++SystemExit++``] is raised when https://docs.python.org/3/library/sys.html#sys.exit[``++sys.exit()++``] is called. This exception is expected to propagate up until the application stops. It is ok to catch it when a clean-up is necessary but it should be raised again immediately.


A https://docs.python.org/3/reference/compound_stmts.html#the-try-statement[bare ``++except:++`` statement], i.e. an ``++except++`` without any exception class, is equivalent to https://docs.python.org/3/library/exceptions.html#BaseException[``++except BaseException++``]. Both statements will catch every exception, including ``++SystemExit++``. It is recommended to catch instead a specific exception. If it is not possible, the exception should be raised again.


Note that it is also a good idea to reraise the https://docs.python.org/3/library/exceptions.html#KeyboardInterrupt[``++KeyboardInterrupt++``] exception.


This rule raises an issue when a bare ``++except:++``, an ``++except BaseException++`` or an ``++except SystemExit++`` don't reraise the exception caught.


=== Noncompliant code example

[source,python]
----
try:
    open("foo.txt", "r")
except SystemExit:  # Noncompliant
    pass
except KeyboardInterrupt:  # No issue raised but be careful when you do this
    pass

try:
    open("bar.txt", "r")
except BaseException:  # Noncompliant
    pass
except:  # Noncompliant
    pass
----


=== Compliant solution

[source,python]
----
try:
    open("foo.txt", "r")
except SystemExit:
    # clean-up
    raise
except KeyboardInterrupt:
    # clean-up
    raise

try:
    open("bar.txt", "r")
except BaseException as e:
    # clean-up
    raise e
except: # Noncompliant
    # clean-up
    raise

# or use a more specific exception

try:
    open("bar.txt", "r")
except FileNotFoundError:
    # process the exception
----


== Resources

* PEP 352 - https://www.python.org/dev/peps/pep-0352/#id5[Required Superclass for Exceptions]
* Python Documentation - https://docs.python.org/3/library/exceptions.html[Built-in exceptions]
* Python Documentation - https://docs.python.org/3/reference/compound_stmts.html#the-try-statement[The ``++try++`` statement]
* https://cwe.mitre.org/data/definitions/391[MITRE, CWE-391] - Unchecked Error Condition


ifdef::env-github,rspecator-view[]

'''
== Implementation Specification
(visible only on this page)

=== Message

* if it is a bare "except:":
* specify an exception class to catch or reraise the exception.
* if it catches a BaseException:
* catch a more specific exception or reraise the exception.
* if SystemExit is caught:the application as the user expects.


=== Highlighting

the "except" statement


'''
== Comments And Links
(visible only on this page)

=== relates to: S1181

=== relates to: S2142

=== relates to: S2738

=== on 6 Mar 2020, 15:05:41 Nicolas Harraudeau wrote:
This rule is similar to RSPEC-2142 but this one is a code smell because python 2 forced developers to use a bare ``++except:++`` for a long time. Thus old projects will have many issues. Yet even in python 2 it is possible to handle properly the exception. Thus we raise a code smell issue for both python 2 and python 3.

endif::env-github,rspecator-view[]
