Except 块处理“BaseException”¶
ID: py/catch-base-exception
Kind: problem
Security severity:
Severity: recommendation
Precision: very-high
Tags:
- reliability
- readability
- convention
- external/cwe/cwe-396
Query suites:
- python-security-and-quality.qls
Python 中所有异常类都派生自 BaseException
。 BaseException
有三个重要的子类,Exception
,所有错误和普通异常都派生自它,KeyboardInterrupt
,当用户从键盘中断程序时引发它,以及 SystemExit
,它由 sys.exit()
函数引发以终止程序。
由于 KeyboardInterrupt
和 SystemExit
是特殊的,因此不应该将它们与其他 Exception
类分组在一起。
捕获 BaseException
而不是它的子类可能会阻止正确处理 KeyboardInterrupt
或 SystemExit
。由于空 except:
语句会隐式捕获它,因此很容易意外地捕获 BaseException
。
建议¶
分别处理 Exception
、KeyboardInterrupt
和 SystemExit
。不要使用简单的 except:
形式。
示例¶
在这些示例中,调用了一个可能引发 SystemExit
的函数 application.main()
。在前两个函数中,捕获了 BaseException
,但这会丢弃 KeyboardInterrupt
。在第三个函数 call_main_program_fixed
中,只捕获了 SystemExit
,使 KeyboardInterrupt
传播。
在这些示例中, KeyboardInterrupt
被意外忽略。
def call_main_program_implicit_handle_base_exception():
try:
#application.main calls sys.exit() when done.
application.main()
except Exception as ex:
log(ex)
except:
pass
def call_main_program_explicit_handle_base_exception():
try:
#application.main calls sys.exit() when done.
application.main()
except Exception as ex:
log(ex)
except BaseException:
pass
def call_main_program_fixed():
try:
#application.main calls sys.exit() when done.
application.main()
except Exception as ex:
log(ex)
except SystemExit:
pass