in tools/pylint-extensions/azure-pylint-guidelines-checker/pylint_guidelines_checker.py [0:0]
def check_for_logging(self, node, exception_name):
""" Helper function - Called from 'check_for_raise' function
Checks if the same exception that's being raised is also being logged
"""
try:
# Find all function calls in the code
for j in node:
if isinstance(j, astroid.Expr) and isinstance(j.value.func, astroid.Attribute):
# check that the attribute is a logging level
if j.value.func.attrname in ["debug", "info", "warning", "error", "exception", "critical"]:
# Check all arguments to the logger
# The exception could be logged in various ways:
# 1. logger.debug(exception)
# 2. logger.debug(f"something {exception}")
# 3. logger.debug("Failed: %r", exception)
# if we have exception.__name__ or str(exception) lets not raise an error
for log_arg in j.value.args:
# Check for calls like str(exception) or exception.__name__
if isinstance(log_arg, astroid.Call) and isinstance(log_arg.func, astroid.Name) and log_arg.func.name == "str":
for arg in log_arg.args:
if isinstance(arg, astroid.Name) and arg.name == exception_name:
# This is str(exception), which is fine
return
# Check for attribute access like exception.__name__
if isinstance(log_arg, astroid.Attribute) and isinstance(log_arg.expr, astroid.Name):
if log_arg.expr.name == exception_name and log_arg.attrname == "__name__":
# This is exception.__name__, which is fine
return
# Check for f-strings that might contain the exception
for log_arg in j.value.args:
if isinstance(log_arg, astroid.Name) and log_arg.name == exception_name:
self.add_message(
msgid="do-not-log-raised-errors",
node=j,
confidence=None,
)
return
if isinstance(log_arg, astroid.Call):
for arg in log_arg.args:
if isinstance(arg, astroid.Name) and arg.name == exception_name:
self.add_message(
msgid="do-not-log-raised-errors",
node=j,
confidence=None,
)
return
if isinstance(log_arg, astroid.JoinedStr):
for value in log_arg.values:
if isinstance(value, astroid.FormattedValue):
try:
if isinstance(value.value, astroid.Name) and value.value.name == exception_name:
self.add_message(
msgid="do-not-log-raised-errors",
node=j,
confidence=None,
)
return
except AttributeError:
pass
# Check for string formatting with exception as argument
if len(j.value.args) > 1:
for idx in range(1, len(j.value.args)):
if isinstance(j.value.args[idx], astroid.Name) and j.value.args[idx].name == exception_name:
self.add_message(
msgid="do-not-log-raised-errors",
node=j,
confidence=None,
)
return
except:
pass