0

The following function connects to an API and returns a json object. Although it only works on development. In the production server it just returns False.

Any ideas why it doesn't work in a different server?

def request_api(api_call, post_fields, authentication_data = None):
    try:
        log.debug("Connecting To API: " + settings.API_URL + api_call)
        curl = pycurl.Curl()
        curl.setopt(pycurl.URL, settings.API_URL + api_call)
    except:
        log.debug("Can't connect To API: " + settings.API_URL + api_call)
    if post_fields:
        try:
            log.debug("Post Fields: " + post_fields)
            curl.setopt(curl.POSTFIELDS, str(post_fields))
        except:
            log.debug("Error setting post fields.")
    if authentication_data:
        try:
            log.debug("Authentication Fields: " + authentication_data)
            curl.setopt(pycurl.USERPWD, authentication_data)
        except:
            log.debug("Error during authentication.")
    try:
        contents = StringIO.StringIO()
        curl.setopt(pycurl.WRITEFUNCTION, contents.write)
        curl.perform()
    except:
        log.debug("Error on curl.")
    try:
        responseCode = curl.getinfo(pycurl.HTTP_CODE);
        log.debug("Response Code: " + str(responseCode))
    except:
        log.debug("Response Code: Error")
    try:
        log.debug("Response: " + contents.getvalue())
    except:
        log.debug("Response: Error")
    try:
        pyobj = json.loads(contents.getvalue())
        log.debug("Response In Json Format: " + str(pyobj))
    except:
        log.debug("Response In Json Format: Error")
    return pyobj

Error:

Exception Type:     UnboundLocalError
Exception Value:    

local variable 'pyobj' referenced before assignment

Log File:

[18/Sep/2012 04:07:52] DEBUG [contests.views:29] Connecting To API: https://my-api/v1/token
[18/Sep/2012 04:07:52] DEBUG [contests.views:39] Authentication Fields: test@user.com:test@user.com
[18/Sep/2012 04:49:32] DEBUG [contests.views:51] Error on curl.
[18/Sep/2012 04:49:32] DEBUG [contests.views:54] Response Code: 0
[18/Sep/2012 04:49:32] DEBUG [contests.views:58] Response: 
[18/Sep/2012 04:49:32] DEBUG [contests.views:65] Response In Json Format: Error
ipegasus
  • 14,796
  • 9
  • 52
  • 76
  • Your code is full of catch-all exception handlers, which is not a recommended practice. The whole thing returns False on any uncaught exception. You should just remove them, or catch something more specific. This is probably hiding the real error. – Keith Sep 18 '12 at 04:37
  • Thank you for the suggestion. It makes the error more clear. I updated the question and messages accordingly. Any ideas why it works in my local server but not in a different one? – ipegasus Sep 18 '12 at 04:54
  • That pattern of catch-all exceptions and logging is just not "Pythonic". You should first write your code without any of them. Then debug it. Then leave them out. Only catch exceptions if you can do something meaningful with it. In this case, there is some error in either getting the value from contents, or malformed content. But we can't tell. Then you try to return the non-existent object. That doesn't make sense, which is why you should just let the exception propogate up. Don't catch it here. – Keith Sep 18 '12 at 14:34
  • Thank you very much. That solved the issue. Without try except I tracked the real issue. – ipegasus Sep 18 '12 at 17:46

1 Answers1

2

What's causing the immediate error is this:

try:
    pyobj = json.loads(contents.getvalue())
    log.debug("Response In Json Format: " + str(pyobj))
except:
    log.debug("Response In Json Format: Error")
return pyobj

The try clause is failing, as you can see in your log, which means pyobj isn't being defined. When you try to return it at the end of the function, it doesn't exist, so you get an UnboundLocalError.

Why this section is failing will have to do with either contents.getValue crashing or passing something inappropriate to json.loads. However, because you are catching all exceptions and returning your own less than helpful error messages, you are hiding all of the relevant traceback information that would help you realise where the problem really lies. The traceback will tell you exactly what the error is and where it occurred down to the file & line of code, which will be of much more use to you than Response In Json Format: Error.

Matthew Trevor
  • 14,354
  • 6
  • 37
  • 50