infobloxopen/infoblox-client

Unable to capture 500 errors

Closed this issue · 1 comments

Hello,
currently, it seems not possible to distinguish 404 errors from 5XX using connector's _get_object.

if r.status_code != requests.codes.ok:
LOG.warning("Failed on object search with url %s: %s",
url, r.content)
return None

the connector threat all http error exactly the same. as a result all get_object query are returning None object

# Example to reproduce the issue with requests-mock
import pytest
from infoblox_client import connector


def test_infoblox_client_error(requests_mock):
  requests_mock.get(
    "https://example.com/wapi/v2.10.3/zone_auth?",
    text="",
    status_code=500
  )
  conn = connector.Connector(
    {
      "host": "example.com",
      "username": "foo",
      "password": "bar",
      "wapi_version": "2.10.3"
    }
  )
  error_500 = conn.get_object('zone_auth')

  requests_mock.get(
    "https://example.com/wapi/v2.10.3/zone_auth?",
    text="",
    status_code=404
  )
  conn = connector.Connector(
    {
      "host": "example.com",
      "username": "foo",
      "password": "bar",
      "wapi_version": "2.10.3"
    }
  )
  error_404 = conn.get_object('zone_auth')
  assert error_404 != error_500, "Unable to distinguish 404 from 500 error"

Unfortunately, sometimes the infoblox api is returning 5XX error. It would be a good improvement to raise an error for unexpected results.

In worst case scenario the api is called twice. that could affect infoblox api performances.

# Do second get call with force_proxy if not done yet
if self.cloud_api_enabled and not force_proxy:
ib_object = self._handle_get_object(obj_type, query_params,
extattrs, proxy_flag=True)
if ib_object:
return ib_object
return None

also the name "InfobloxObjectNotFound" is visible in get_object's docstring, but never use.

Returns:
A list of the Infoblox objects requested
Raises:
InfobloxObjectNotFound

thank you a lot for your help

@H0neyBadger

Updated Connector's _get_object method to raise requests HTTPError in case of incorrect HTTP response. This exception will be wrapped with InfobloxConnectionError by reraise_neutron_exception decorator.

So, if you want to process HTTP errors differently, you'll have to catch InfobloxConnectionError and then process it's kwargs attribute like this:

try:
    obj = conn.get_object('zone_auth')
except infoblox.exceptions.InfobloxConnectionError as e:
    status_code = e.kwargs["reason"].reponse.status_code
    if status_code == 404:
        print("Not Found!")
    if status_code == 500:
        print("Internal Server Error")

Feel free to review PR #292, and ask questions/propose changes if you have any.