Python – Handling Error Codes from an External XML API

apierror handlingpythonweb-api

Problem

I have a Python library which sends XML requests to an external API. If an issue occurs, the API responds with an error containing an error code and description with error details.

These errors can be caused by anything from malformed XML data, an invalid username/password, editing a read-only attribute, or trying to load data that doesn't exist.

<Response Status="Failure" Action="LoadByName">
    <Error Message="WFP-00235 The job name does not exist in the database." ErrorCode="17" AtIndex="0"/>
</Response>

Current approach

Because I can't control the response I'll receive, my library currently handles any exceptions by raising a RuntimeError with the message received from the API.

import xml.etree.ElementTree as ElementTree

def parse_response(xml):
    # Check if XML response contains any errors
    if xml.find(".//Error") is not None:
        raise RuntimeError(xml.find(".//Error").get("Message"))
    ...

RuntimeError: WFP-00235 The job name does not exist in the database.

One major flaw with this approach is that the ErrorCode isn't preserved when an exception is raised. This makes it impossible to catch specific API errors, as each error is essentially a generic exception.

Question

How should I handle XML errors that come from an external API? Can I raise/catch errors based on their numeric ErrorCode?

Best Answer

I would suggest that you avoid using a general exception in this case. General "something happened" type exceptions are fine for situations where there is nothing reasonable you can do about it.

In this case you seem to care about the various errors. The simplest way to do this is to create a single exception type that can hold the all the error data.

class UhOhError(Exception):
  def __init__(self, message, errorcode, errordata):
    super(UhOhError, self).__init__(message)
    self.errorcode = errorcode
    self.errordata = errordata

Then you have access to those fields wherever you want to catch it. If you know what all of these errors are going to be and have different actions you want to take given the various problems, you might want to have various exception types. That makes the exception handling easier because you declare which errors you want to catch in various places simply the except clause alone.

You can even do both, a single exception type for most things and a specific type for issues that you need to single out and treat differently.

Related Topic