def check_for_logging()

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