-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
logging: propagate errors during log message emits #7231
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Currently, a bad logging call, e.g.
logger.info('oops', 'first', 2)
triggers the default logging handling, which is printing an error to
stderr but otherwise continuing.
For regular programs this behavior makes sense, a bad log message
shouldn't take down the program. But during tests, it is better not to
skip over such mistakes, but propagate them to the user.
|
Relevant doc is here: https://docs.python.org/3/library/logging.html#logging.Handler.handleError |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice!
|
|
||
| def handleError(self, record: logging.LogRecord) -> None: | ||
| # Handled by LogCaptureHandler. | ||
| pass |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest to change those pass to a docstring to "trick" coverage 😁
def handleError(self, record: logging.LogRecord) -> None:
"""Handled by LogCaptureHandler."""There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hehe I didn't know it would trick it.
Actually it really isn't covered so I prefer not to. I don't think it worth covering really, but if someone ever wants 100% coverage, they'd need to :)
If lineno is set to None in the LogRecord, pytest's logging formatting fails:
tests/unit/utils/test_log.py:418: in test_empty_message
log.qt_message_handler(QtCore.QtDebugMsg, self.Context(), "")
qutebrowser/utils/log.py:508: in qt_message_handler
qt.handle(record)
/usr/lib/python3.8/logging/__init__.py:1587: in handle
self.callHandlers(record)
/usr/lib/python3.8/logging/__init__.py:1649: in callHandlers
hdlr.handle(record)
/usr/lib/python3.8/logging/__init__.py:950: in handle
self.emit(record)
../../pytest/src/_pytest/logging.py:326: in emit
super().emit(record)
/usr/lib/python3.8/logging/__init__.py:1089: in emit
self.handleError(record)
/usr/lib/python3.8/logging/__init__.py:1081: in emit
msg = self.format(record)
/usr/lib/python3.8/logging/__init__.py:925: in format
return fmt.format(record)
../../pytest/src/_pytest/logging.py:89: in format
return super().format(record)
/usr/lib/python3.8/logging/__init__.py:667: in format
s = self.formatMessage(record)
/usr/lib/python3.8/logging/__init__.py:636: in formatMessage
return self._style.format(record)
../../pytest/src/_pytest/logging.py:185: in format
return self._fmt % record.__dict__
E TypeError: %d format: a number is required, not NoneType
According to typeshed, lineno should never be None:
https://github.com/python/typeshed/blob/028f0d52931fe1f96bb25d066186961159c1f801/stdlib/2and3/logging/__init__.pyi#L386
Thus, this is our fault, not pytest's. However, before pytest 6.0.0, pytest did
not surface logging errors:
pytest-dev/pytest#7231
pytest-dev/pytest@b13fcb2
Thus, we never noticed something was going wrong here.
If lineno is set to None in the LogRecord, pytest's logging formatting fails:
tests/unit/utils/test_log.py:418: in test_empty_message
log.qt_message_handler(QtCore.QtDebugMsg, self.Context(), "")
qutebrowser/utils/log.py:508: in qt_message_handler
qt.handle(record)
/usr/lib/python3.8/logging/__init__.py:1587: in handle
self.callHandlers(record)
/usr/lib/python3.8/logging/__init__.py:1649: in callHandlers
hdlr.handle(record)
/usr/lib/python3.8/logging/__init__.py:950: in handle
self.emit(record)
../../pytest/src/_pytest/logging.py:326: in emit
super().emit(record)
/usr/lib/python3.8/logging/__init__.py:1089: in emit
self.handleError(record)
/usr/lib/python3.8/logging/__init__.py:1081: in emit
msg = self.format(record)
/usr/lib/python3.8/logging/__init__.py:925: in format
return fmt.format(record)
../../pytest/src/_pytest/logging.py:89: in format
return super().format(record)
/usr/lib/python3.8/logging/__init__.py:667: in format
s = self.formatMessage(record)
/usr/lib/python3.8/logging/__init__.py:636: in formatMessage
return self._style.format(record)
../../pytest/src/_pytest/logging.py:185: in format
return self._fmt % record.__dict__
E TypeError: %d format: a number is required, not NoneType
According to typeshed, lineno should never be None:
https://github.com/python/typeshed/blob/028f0d52931fe1f96bb25d066186961159c1f801/stdlib/2and3/logging/__init__.pyi#L386
Thus, this is our fault, not pytest's. However, before pytest 6.0.0, pytest did
not surface logging errors:
pytest-dev/pytest#7231
pytest-dev/pytest@b13fcb2
Thus, we never noticed something was going wrong here.
(cherry picked from commit e206d34)
Make mypy happy
It doesn't know about QMessageLogContext.lineno being Optional[int] rather than
int.
(cherry picked from commit 4136c84)
Fixes #6433.
Currently, a bad logging call, e.g.
triggers the default logging handling, which is printing an error to
stderr but otherwise continuing.
For regular programs this behavior makes sense, a bad log message
shouldn't take down the program. But during tests, it is better not to
skip over such mistakes, but propagate them to the user.