Reputation: 311
I'm having an issue providing custom response handling for cherrypy.HTTPError
. The only content that I want displayed in the body of the response is a JSON-encoded dict (this is REST API). The source code seems to indicate that HTTPError.set_response()
can be used to modify the cherrypy.response
object ... to quote the comment in this method:
Modify cherrypy.response status, headers, and body to represent self. CherryPy uses this internally, but you can also use it to create an HTTPError object and set its output without *raising* the exception.
I have sub-classed HTTPError to provide my own body for the response. I call the base class methods to ensure that any necessary housekeeping takes place.
class APIError(cherrypy.HTTPError):
def __init__(self, err_resp):
super().__init__(status=err_resp['error_code'])
self._api_err_resp = err_resp
def set_response(self):
super().set_response()
response = cherrypy.serving.response
response.body = json.dumps(self._api_err_resp).encode()
I can now call APIError
without a problem, but the issue I have is that the CherryPy web server takes approx 10-15sec to respond to my client once my custom error is raised (I experience no delay if I use HTTPError
). I've traced the source code, but can't find the cause of the delay.
Any help would be appreciated.
Rob
Upvotes: 5
Views: 1421
Reputation: 712
I got it to work with this approach, which takes esp. into account jmpcm's comment on setting the content length:
class APIError(cherrypy.HTTPError):
def __init__(self, status=500, message=None):
super().__init__(status=status, message=message)
self._json_error = json.dumps({'error': message}).encode('utf-8')
def set_response(self):
super().set_response()
response = cherrypy.serving.response
response.body = self._json_error
response.headers["Content-Length"] = len(self._json_error)
response.headers['Content-Type'] = 'application/json'
``
Upvotes: 0
Reputation: 8382
Using cherrypy 16.0.2 on Python 3.7.2, 64bit, windows7 subclassing HTTPError does not cause unusual waiting times. Maybe you should try with a current version of cherrypy.
This is the code I used to test it:
import cherrypy as cp
class APIError(cp.HTTPError):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self._json_error = kwargs
def set_response(self):
super().set_response()
response = cp.serving.response
response.body = json.dumps({'error': self._json_error}).encode('utf-8')
This example requires you to call APIError with the proper keywords status and message. For production use, I wrote a larger class where I pass status, json data and other data for logging and then call the super().__init__
with only the status code.
Upvotes: 1