Hacker News new | ask | show | jobs
by olsgaarddk 2290 days ago
Kinda off-topic, since the article is about not making errors, instead of logging them, but sometimes you are not in control of input, and you expect some exceptions that you want to log.

In Python, instead of the example in the blog:

    try:
        do_something_complex(*args, **kwargs)
    except MyException as ex:
        logger.log(ex)
Use the almost undocumented `exc_info=True`, like this

    try:
        do_something_complex(*args, **kwargs)
    except MyException as ex:
        logger.error(ex, exc_info=True)
This will log the entire exception.

Even cooler, every un-caught exception calls `sys.excepthook()`. The function is supposed to be monkey patched by anyone who wants to do something with uncaught exceptions, so you can do the following if you want to log all uncaught exceptions:

    def exception_logger_hook(exc_type, exc_value, exc_traceback):
        logger.error("Uncaught exception", exc_info=(exc_type, exc_value, exc_traceback))
        sys.__excepthook__(exc_type, exc_value, exc_traceback)
    
    sys.excephook = exception_logger_hook
This will send all uncaught exceptions to the logger and then continue with raising the exception normally.
2 comments

> Use the almost undocumented `exc_info=True`

Why not simply use logger.exception()?

  try:
      do_thing()
  except Exception:
      logger.exception("It broke.")
Called from within an exception handler, logger.exception() automatically includes exception information.
Mostly because I didn't know of it. But also if you want to log caught exceptions as debug, because you were expecting the exception. E.g., a StopIteration exception you for some reason might want information about, or you have an object you need to check if it has a certain key, but for some reason doesn't have a get-method.

I'm sure there are also good reasons :)

TIL, thank you sir. Gonna try this out tomorrow.