Learning Python for Forensics
上QQ阅读APP看书,第一时间看更新

Troubleshooting

At some point in your development career—probably by the time you write our first script—you will have encountered a Python error and received a Traceback message. The Traceback provides the context of the error and pinpoints the line that caused the issue. The issue itself is an exception and message of the error.

Python has a number of built-in exceptions whose purpose is to help the developer to diagnose errors in their code. Appendix B, Python Technical Details details solutions to common exceptions. It is not, however, an exhaustive list as some less common and user-created exceptions are not covered. A full list of built-in exceptions can be found at http://docs.python.org/2/library/exceptions.html.

Let's look at a simple example of an exception, AttributeError, and what the Traceback looks like in this case:

>>> import math
>>> print math.noattribute(5)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'noattribute'

The Traceback indicates the file in which the error occurred (in this case, stdin or standard input) because this code was written in the interactive prompt. When working on larger projects or with a single script, the file will be the name of the error-causing script rather than stdin. The in <module> bit will be the name of the function that contains the faulty line of code or <module> if the code is not in a function.

Now, let's look at a slightly more complicated issue. To do this, we will remove a try and except block from the usb_lookup.py script we've written. We're going to remove lines 75 and 77-79. Remember to unindent what was line 76 in order to avoid IndentationError.

Before removing the mentioned lines, it looks as follows:

075     try:
076         vendor = usb_dict[vendor_key][0]
077     except KeyError:
078         print 'Vendor Id not found.'
079         sys.exit(0)

After removing the mentioned lines, it looks as follows::

076     vendor = usb_dict[vendor_key][0]

Now run the script and supply a vendor ID that does not exist:

python usb_lookup.py ffff ffff
Traceback (most recent call last):
  File "usb_lookup.py", line 93, in <module>
    main()
  File "usb_lookup.py", line 40, in main
    search_key(usbs)
  File "usb_lookup.py", line 75, in search_key
    vendor = usb_dict[vendor_key][0]
KeyError: 'ffff'

The traceback here has three traces in the stack. The last trace at the bottom is where our error occurred. In this case, on line 75 of the usb_lookup.py file, the search_key() function generated a KeyError exception. Looking up what a KeyError is in the Python documentation or Appendix B, Python Technical Details would indicate that this is due to the key that does not exist in the dictionary. Most of the time, we will need to address the error at that specific error-causing line. For this reason, line 75 was surrounded by a try and except block to catch and exit the program when the vendor was not found.