Reputation: 556
Making a request to the server, as in code below, I've got status code 500, which was not caught as an exception. The output was "500", but I need for all 500 codes to result in sys.exit(). Does requests.exceptions.RequestException not treat 500 as an exception or is it something else? The requests module docs http://docs.python-requests.org/en/latest/user/quickstart/#errors-and-exceptions are not very clear on what falls under this class. How do I make sure that all 500 codes result in sys.exit()?
import requests
import json
import sys
url = http://www.XXXXXXXX.com
headers = {'user':'me'}
try:
r = requests.post(url, headers=headers)
status = r.status_code
response = json.dumps(r.json(), sort_keys=True, separators=(',', ': '))
print status
except requests.exceptions.RequestException as e:
print "- ERROR - Web service exception, msg = {}".format(e)
if r.status_code < 500:
print r.status_code
else:
sys.exit(-1)
Upvotes: 10
Views: 26163
Reputation: 59
Following might help.
Generic Flask error handling functions with HTTP_RESPONSE_CODE based annotations:
listing for controller\http_error_handler.py:
from flask import make_response
def init_handle_http_errors(app):
def prepare_error_response(error, http_error_code, invoking_handler):
result = {}
result["result"] = {
"outcome": "Failure!",
"detail": repr(error),
"error_type": str(type(error)),
"handler": invoking_handler
}
response = make_response(result, http_error_code)
response.headers["Content-Type"] = "application/json"
return response
#Client errors
@app.errorhandler(400) # Bad Request
def handle_400(error):
return prepare_error_response(error, 400, "400")
@app.errorhandler(404) # Not Found
def handle_404(error):
return prepare_error_response(error, 404, "404")
@app.errorhandler(405) # Method Not Allowed
def handle_405(error):
return prepare_error_response(error, 405, "405")
#Server errors
@app.errorhandler(500) # Internal Server Error
def handle_500(error):
return prepare_error_response(error, 500, "500")
@app.errorhandler(501) # Not Implemented
def handle_501(error):
return prepare_error_response(error, 501, "501")
#Generic unknown error(s)
@app.errorhandler(Exception) # Catch all
def handle_exception(error):
return prepare_error_response(error, 500, "catch all")
Tester endpoint:
@app.route("/mockhttperrors", defaults={"http_error_code": 404}, methods=["GET"])
@app.route("/mockhttperrors/<http_error_code>", methods=["GET"])
def mock_http_error_response(http_error_code: str):
abort(int(http_error_code))
Results expected:
Request: https://localhost:8443/mockhttperrors/501
Response:
{
"result": {
"detail": "<NotImplemented '501: Not Implemented'>",
"error_type": "<class 'werkzeug.exceptions.NotImplemented'>",
"handler": "501",
"outcome": "Failure!"
}
}
Request: https://localhost:8443/mockhttperrors/404
Response:
{
"result": {
"detail": "<NotFound '404: Not Found'>",
"error_type": "<class 'werkzeug.exceptions.NotFound'>",
"handler": "404",
"outcome": "Failure!"
}
}
Request: https://localhost:8443/mockhttperrors/unknown-error (runtime errors)
Response:
{
"result": {
"detail": "ValueError(\"invalid literal for int() with base 10: 'unknown-error'\")",
"error_type": "<class 'ValueError'>",
"handler": "catch all",
"outcome": "Failure!"
}
}
This can be easily extended to accommodate for any any every type of HTTP response codes that need to be handled gracefully and return appropriate 'status code' back to the caller (client)
Upvotes: 0
Reputation: 835
From the Requests documentation:
If we made a bad request (a 4XX client error or 5XX server error response), we can raise it with Response.raise_for_status():
>>> bad_r = requests.get('http://httpbin.org/status/404') >>> bad_r.status_code 404 >>> bad_r.raise_for_status() Traceback (most recent call last): File "requests/models.py", line 832, in raise_for_status raise http_error requests.exceptions.HTTPError: 404 Client Error
So, use
r = requests.post(url, headers=headers)
try:
r.raise_for_status()
except requests.exceptions.HTTPError:
# Gave a 500 or 404
else:
# Move on with your life! Yay!
Upvotes: 9
Reputation: 78556
A status code 500 is not an exception. There was a server error when processing the request and the server returned a 500; more of a problem with the server than the request.
You can therefore do away with the try-except
:
r = requests.post(url, headers=headers)
status = r.status_code
response = json.dumps(r.json(), sort_keys=True, separators=(',', ': '))
if str(status).startswith('5'):
...
Upvotes: 12
Reputation: 26717
If you want a successful request, but "non-OK" response to raise an error, call response.raise_for_status()
. You can then catch that error and handle it appropriately. It will raise a requests.exceptions.HTTPError
that has the response
object hung onto the error.
Upvotes: 8