Python Automation Cookbook
上QQ阅读APP看书,第一时间看更新

How it works...

To properly capture any unexpected exceptions, the main function should be wrapped into a try-except block, as done in Step 4 in the How to do it… section. Compare this to how Step 1 is not wrapping the code:

    try:
main(...)
except Exception as exc:
# Something went wrong
logging.exception("Error running task")
exit(1)

Note that logging the exception is important for getting information on what went wrong.

This kind of exception is nicknamed Pokémon, because it can catch'em all, as it will capture any unexpected error at the highest level. Do not use it in other areas of the code, as capturing everything can hide unexpected errors. At the very least, any unexpected exception should be logged to allow for further analysis.

The extra step to exit with status 1 with the exit(1) call informs the operating system that something went wrong with our script.

The logging module allows us to log. Note the basic configuration, which includes an optional file to store the logs, the format, and the level of the logs to display.

The available level for logs are, from less critical to more critical— DEBUG, INFO, WARNING, ERROR, and CRITICAL. The logging level will set the minimal severity required to log the message. For example, an INFO log won't be stored if the severity is set to WARNING.

Creating logs is easy. You can do this by making a call to the method logging.<logging level>, (where logging level is debug, info, and so on). For example:

>>> import logging
>>> logging.basicConfig(level=logging.INFO)
>>> logging.warning('a warning message')
WARNING:root:a warning message
>>> logging.info('an info message')
INFO:root:an info message
>>> logging.debug('a debug message')
>>>

Note how logs with a severity lower than INFO are not displayed. Use the level definition to tweak how much information to display. This may change, for example, how DEBUG logs may be used only while developing the task, but not be displayed when running it. Notice that task_with_error_handling_step4.py is defining the logging level to be DEBUG, by default.

A good definition of log levels is key to displaying relevant information, while reducing spam. It is not easy to set up sometimes, but especially if more than one person is involved, try to agree on exactly what WARNING versus ERROR means to avoid misinterpretations.

logging.exception() is a special case that will create an ERROR log, but it will also include information about the exception, such as the stack trace.

Remember to check logs to discover errors. A useful reminder is to add a note on the results file, like this:

try:
main(args.n1, args.n2, args.output)
except Exception as exc:
logging.exception(exc)
print('There has been an error. Check the logs', file=args.output)