Following our recent post on Java exceptions, it’s time to look at several exception types that frequently occur in Python code, and how Raygun can assist you in diagnosing the cause of them.
Exceptions in Python are well-supported, and have been since Python 1.5 when proper exception objects were introduced (replacing string exceptions which were deprecated in 2.5). Python 2.6 introduces the ‘as’ syntax when one or more (as a tuple) exception types can be defined to be caught by a certain
except block. This makes it simple to port 2.x code to Python 3.
All of the following exceptions are subclasses of Exception and are included in the standard library, which you can subclass yourself to your own types, and are descriptive of the cause in your code. This is used as part of the identity we create when grouping your exceptions intelligently, among other techniques.
Without more ado, here’s a list of python exceptions you’ll frequently encounter, and how Raygun’s Python provider can assist in debugging them.
This represents the action of referencing or assigning to an attribute that doesn’t otherwise exist – the classic null reference. For whatever reason certain parameters which are expected to have a value in the happy case will frequently not at runtime, which causes this exception to be raised.
The official Raygun provider for Python, Raygun4py, will present the backtrace that resulted in the AttributeError, the message will tell you what attribute was the cause, and the upcoming local variables feature will enable you to see the exact state in each frame. This allows you to pinpoint the cause of the error right after you are notified by email.
ValueError will be raised by a function when one of its parameters is of a value that is invalid – an example being divide(numerator, denominator) where 0 is passed in as the second param. As above you can see the offending variable in the error message in the Raygun dashboard, and its value in the local variables throughout the stack (crucially where it comes from and if it gets mutated in some way).
This very common exception will be raised when a certain operation is performed on an unexpected type. If this occurs in a web context due to malformed user input (especially critical in a REST API) the exception may be buried within a log file. It is critical to use an error tracking service like Raygun to ensure you are notified in a timely manner and have all the data needed to debug the exception and push a fix quickly.
When unit testing, AssertErrors will be raised by the unittest(2) module when a unit test fails. You may have your unit tests run by a build server (or service like Travis), and being notified by email that a build has failed often works well. Most likely your tooling will give you a huge text dump of the build log, which you need to manually sift through as tests fail.
Raygun allows you to extend this pattern by sending exceptions as well as raising them during the build process – you get notified by the exact tests that fail with their stack trace. In combination with the deployments feature (with GitHub integration for viewing the actual source code) visualizing regressions between builds is easy and allows you to pinpoint how committed code may have broken the build.
Begin your Raygun trial now
If you’d like to begin integrating a world-class exception tracking solution into your Python code, you can start your 14 day free trial here, no credit card needed. Got questions? Let us know in the comments below and we’ll get back to you pronto (we have great support from real humans). Until next time, keep frying those exceptions!