recurly/recurly-client-python

Unable to distinguish server and client errors in versions >= 3.0.0

Closed this issue · 2 comments

Errors that are a result of a temporary problem with the server (500-599 response code) and errors that are a result of something the user needs to do differently (400-499 response code) should be possible to differentiate. From version 3.0.0 many of these errors inherit from recurly.ApiError and when an error code not explicitly captured is returned by the API an ApiError is raised. As a user of this client I need to be able to differentiate between errors that are a result of a temporary API outage and errors that are a result of my code.

This was a solved problem in 2.x versions with ServerError/ClientError and UnexpectedServerError/UnexpectedClientError:
https://github.com/recurly/recurly-client-python/blob/2.9.11/recurly/errors.py#L276

I can submit a PR if this sounds acceptable. This is the solution I'm suggesting:

  • Add a ServerError/ClientError that inherit from recurly.APIError and add it as parent to every Error class here:
    class BadRequestError(recurly.ApiError):
  • Raise ServerError or ClientError here depending on the value of resp.status and include the value of resp.status in the error message:
  • ApiError should still be raised if a response code > 599 is returned. The value of resp.status should be included in the error message
bhelx commented

Hey @polishmatt

Thanks for the feedback here! We're aware of the issue and are planning on changing this in the next API version. We'd like to get a few things changed on the API side to make things more consistent. The error classes will have a specific hierarchy to them and will be delegated by status code similar to how you've described. We would take a PR, but this change touches one of the generated parts of the codebase. So we're going to solve this once for every language and it will be kept up-to-date from our OpenAPI spec. I'm targeting getting these changes ready before the end of the year.

In the mean time, keep in mind that you can in fact get some metadata (such as the status code) from the responses and the errors. See the HTTP Metadata section of the docs.

Makes sense, thanks!