Scifabric / pbs

PYBOSSA command line client

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Improve error messages

alejandrodob opened this issue · comments

For instance, I got a ProjectNotFound exception when trying to create a project (which already makes little sense in itself; as you are trying to create the project it could hardly be found). Investigating, the problem was that I got bad credentials (wrong api key).

While attempting to use PBS, I misconfigured the server/URL and yet PBS returns success:

Project: test_project created!

Adding extra debugging to check_api_error in helpers.py, it's clear that the code could use some improvement for robustness. For example, note that the code does not properly handle cases where there is no status value in the JSON response (e.g., my 404 error due to a bad URI).

def check_api_error(api_response):
    """Check if returned API response contains an error."""
    if type(api_response) == dict and (api_response.get('status') == 'failed'):
        if 'ProgrammingError' in api_response.get('exception_cls'):
            raise DatabaseError(message='PyBossa database error.',
                                error=api_response)
        if ('DBIntegrityError' in api_response.get('exception_cls') and
            'project' in api_response.get('target')):
            msg = 'PyBossa project already exists.'
            raise ProjectAlreadyExists(message=msg, error=api_response)
        if 'project' in api_response.get('target'):
            raise ProjectNotFound(message='PyBossa Project not found',
                                  error=api_response)
        if 'task' in api_response.get('target'):
            raise TaskNotFound(message='PyBossa Task not found',
                               error=api_response)
        else:
            raise exceptions.HTTPError

Instead the code should do something closer to:

def check_api_error(api_response):
    """Check if returned API response contains an error."""
    if 'status' not in api_response:
        msg = "Unable to find 'status' in server response; Misconfigured URL?"
        print(msg)
        print("Server response: %s" % api_response)
        raise Exception(msg)
    if type(api_response) == dict and (api_response.get('status') == 'failed'):
        if 'ProgrammingError' in api_response.get('exception_cls'):
            raise DatabaseError(message='PyBossa database error.',
                                error=api_response)
        if ('DBIntegrityError' in api_response.get('exception_cls') and
            'project' in api_response.get('target')):
            msg = 'PyBossa project already exists.'
            raise ProjectAlreadyExists(message=msg, error=api_response)
        if 'project' in api_response.get('target'):
            raise ProjectNotFound(message='PyBossa Project not found',
                                  error=api_response)
        if 'task' in api_response.get('target'):
            raise TaskNotFound(message='PyBossa Task not found',
                               error=api_response)
        else:
            raise exceptions.HTTPError

I'll create a PR of this for the team's consideration.

Ugh, nevermind. There are inconsistencies throughout the API/client so it's not a simple matter of adding a few checks. All of the PBS tests need to be refactored, ideally adding more simulated information to the mocks. I'm a bit surprised the status/status_code aren't part of the mock testing. That would've allowed for quick[er] refactoring of check_api_error. As it stands, I've invested a couple hours into this refactoring and don't feel confident about it. Will spin up another issue to cover improving the tests.

Hi! Thanks a lot for all the hard work. We know we should improve the API checks, so any help is welcome! Please, check out our CONTRIB guidelines for merging your code. Once you have the PR we'll check it and merge it if it looks ok (which it will) :D