I've been using the python 'requests' module for a while now, until a recent unexpected complication caused me to try system.net.httpPost again.
When i was using 'requests', my code looked something like this:
resp = requests.post(postUrl, headers=urlHeaders, data=payload)
if resp.status_code < 400:
respJSON = system.util.jsonDecode(resp.content)
logger.debug("POST API Success!")
logger.debug(str(respJSON))
return respJSON
else:
logger.error("POST API Error: " + str(resp.status_code) + " - " + str(resp.content))
logger.error("POST API Payload: " + str(payload))
shared.log.scriptError(scriptName + "ERROR: " + str(resp.status_code) + " - " + str(resp.content))
return None
# end if
Which was working our really nice for me, as i could easily detect if the request failed by examining resp.status_code
, and then easily create a descriptive error with resp.content
.
However, now that i'm forced to use net.httpPost, my code looks a bit more like this:
try:
resp = system.net.httpPost(url=postUrl, contentType="application/json",postData=payload, headerValues=urlHeaders, connectTimeout=30000,bypassCertValidation=True, throwOnError=True)
respJSON = system.util.jsonDecode(resp)
logger.debug("POST API Success!")
logger.debug(str(respJSON))
return respJSON
except:
shared.log.scriptError(scriptName + " Error executing API, check error logs for details")
logger.error("POST API failure. Check error logs")
return None
# end try
The problem is, I can no longer extract the useful response content like i did before.
I have tried something from this forum post, where i captured the IOError e, but that returns just the string:
Server returned HTTP response code: 400 for URL: https://api.unleashedsoftware.com/StockAdjustments/cc0ef00f-b663-11ea-9101-7fca5527d026
Which is too generic to be of use to my client to debug.
So i then tried setting throwOnError=False
, which provided the following JSON strings:
SUCCESS:
{u'Status': 'Completed', u'StockAdjustmentLines': [{u'Comments': None, u'SerialNumbers': , u'Product': {u'ProductCode': '5017'.........
FAILURE:
{u'Description': 'Cannot complete stock adjustment that leaves 0 stock with non-zero value. (Product 5017).', u'DebugInformation': None}
So at least with this i can provide a useful error message by looking at the response["Description"] field. However i don't have a reliable way to know whether the response was good or not, as i no longer get the HTTP response Code anymore.
Is there a way to get the best of both worlds here?
I don't really want to resort to something like this, as it doesn't seem particularly robust without knowing all the return options:
if respJSON["Status"] != "Completed" or respJSON["Status"] is None:
logger.error(scriptName + " - " + respJSON["Description"])
return None
else:
return respJSON
# end if