Python exception handling

AppSignal tries to record as many Python exceptions as possible. AppSignal is able to capture exceptions across your application with our instrumentations that extend our support to many popular frameworks and background job packages.

However, there may be scenarios where exceptions are raised that are not related to potential problems in your Python application, such as bots trying to automatically post forms or outdated links that might direct visitors to content that doesn't exist anymore.

To avoid these errors from being raised as problems in AppSignal it's possible to add exception handling to your code or even let AppSignal completely ignore certain errors.

Ignore errors

The AppSignal configuration makes it possible to ignore errors. By providing a list of specific errors AppSignal will not send alerts when these errors are raised.

Exception handling

Simply ignoring an error will silence notifications, but could potentially hide a bigger problem. For this reason we recommend you add exception handling with try .. except statements to your application.

Using try .. except you can catch specific exceptions and add an alternative code path for when an exception occurs, such as rendering 404 pages or providing the user with more detailed error messages about what went wrong.

For example, in a Django view file we can do the following:

python
def show(request): try: user = Post.find(1) except RecordNotFound: return render(request, "not_found.html")

There's a couple of scenarios, such as when resources don't exist or when a form submission fails, that should be handled like this to provide proper HTTP responses to the end-user.

If you want to these report caught errors to AppSignal, use the set_error or send_error helpers.

set_error

Note: This feature was introduced in version 0.3.0 of the Python package.

Report errors, without having them crash your application. Using the set_error helper, the given error is set on the AppSignal trace, which reports the error on the trace (request / background job) to AppSignal.

If you still want to track the error while catching it, you can use the set_error helper to add the exception to the current AppSignal trace. The error will be recorded in AppSignal, but your process will not crash.

For example, in a Django view file we can do the following:

python
from appsignal import set_error # In a Django view file def show(request): try: user = Post.find(1) except Post.DoesNotExist as error: set_error(error) return render(request, "not_found.html")

The exception will be tracked by AppSignal like any other error, and it allows you to provide custom error handling and fallbacks.

Note: This method only works when there is an AppSignal trace already active. Otherwise the error will be ignored. This is true in most automatically supported instrumentations or when using custom instrumentation. Please see send_error for sending errors without an active AppSignal trace.

send_error

Note: This feature was introduced in version 0.3.0 of the Python package.

AppSignal provides a mechanism to send errors to AppSignal without having to start a trace. This is useful for tracking errors that occur in code that's not in a web request or background job context, such as one off scripts or cron jobs.

This is useful for apps that do not use our instrumentations for this part of the app in which the error is raised.

You can use the send_error method to directly send an exception to AppSignal from any place in your code without starting a trace first.

python
from appsignal import send_error # In a script def perform(): try: user = Post.find(1) except Post.DoesNotExist as error: send_error(error) print("No post found!")

Additional metadata

To add metadata to the sent error, use the send_error_with_context method. Tags and sample data can be added to the error this way.

python
from appsignal import send_error # In a script def perform(): try: user = Post.find(1) except Post.DoesNotExist as error: # Using implicit current span with send_error_with_context(error): set_params({"abc": "def"}) # Using explicit `with` block span with send_error_with_context(error) as current_span: set_params({"abc": "def"}, current_span) print("No post found!")