I am running Tornado with stream_request_body
and saving a file POST
request to file on server. In prepare
I create the file object and in post
I close
file object. How do I capture any error/exception in data_received
so that I can close
the file object properly?
from tornado.ioloop import IOLoop from tornado.web import Application, RequestHandler, stream_request_body @stream_request_body class UploadHandler(RequestHandler): def prepare(self): self.file = open('uploaded_file', 'wb') def data_received(self, chunk): print(len(chunk)) self.file.write(chunk) # force an exception raise Exception('Error') def post(self, *args, **kwargs): self.file.close() self.write('UPLOADED') app = Application([(r'/upload', UploadHandler), ], debug=True) if __name__ == '__main__': app.listen(7777) IOLoop.current().start()
terminal output where tornado app is running
$ python upload.py 232 ERROR:tornado.application:Uncaught exception Traceback (most recent call last): File "/prog/res/komodo/2021.08.03-py36-rhel7/root/lib64/python3.6/site-packages/tornado/http1connection.py", line 659, in _read_fixed_body ret = delegate.data_received(body) File "/prog/res/komodo/2021.08.03-py36-rhel7/root/lib64/python3.6/site-packages/tornado/routing.py", line 264, in data_received return self.delegate.data_received(chunk) File "/prog/res/komodo/2021.08.03-py36-rhel7/root/lib64/python3.6/site-packages/tornado/web.py", line 2279, in data_received return self.handler.data_received(data) File "upload.py", line 13, in data_received raise Exception('Error') Exception: Error
terminal output with python interpreter for the request
>>> resp=requests.post('http://localhost:7777/upload', files={'file': open('test.txt', 'rb')}) Traceback (most recent call last): File "/prog/res/komodo/2021.08.03-py36-rhel7/root/lib/python3.6/site-packages/urllib3/connectionpool.py", line 706, in urlopen chunked=chunked, File "/prog/res/komodo/2021.08.03-py36-rhel7/root/lib/python3.6/site-packages/urllib3/connectionpool.py", line 445, in _make_request six.raise_from(e, None) File "<string>", line 3, in raise_from File "/prog/res/komodo/2021.08.03-py36-rhel7/root/lib/python3.6/site-packages/urllib3/connectionpool.py", line 440, in _make_request httplib_response = conn.getresponse() File "/usr/lib64/python3.6/http/client.py", line 1346, in getresponse response.begin() File "/usr/lib64/python3.6/http/client.py", line 307, in begin version, status, reason = self._read_status() File "/usr/lib64/python3.6/http/client.py", line 276, in _read_status raise RemoteDisconnected("Remote end closed connection without" http.client.RemoteDisconnected: Remote end closed connection without response During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/prog/res/komodo/2021.08.03-py36-rhel7/root/lib/python3.6/site-packages/requests/adapters.py", line 449, in send timeout=timeout File "/prog/res/komodo/2021.08.03-py36-rhel7/root/lib/python3.6/site-packages/urllib3/connectionpool.py", line 756, in urlopen method, url, error=e, _pool=self, _stacktrace=sys.exc_info()[2] File "/prog/res/komodo/2021.08.03-py36-rhel7/root/lib/python3.6/site-packages/urllib3/util/retry.py", line 532, in increment raise six.reraise(type(error), error, _stacktrace) File "/prog/res/komodo/2021.08.03-py36-rhel7/root/lib/python3.6/site-packages/urllib3/packages/six.py", line 734, in reraise raise value.with_traceback(tb) File "/prog/res/komodo/2021.08.03-py36-rhel7/root/lib/python3.6/site-packages/urllib3/connectionpool.py", line 706, in urlopen chunked=chunked, File "/prog/res/komodo/2021.08.03-py36-rhel7/root/lib/python3.6/site-packages/urllib3/connectionpool.py", line 445, in _make_request six.raise_from(e, None) File "<string>", line 3, in raise_from File "/prog/res/komodo/2021.08.03-py36-rhel7/root/lib/python3.6/site-packages/urllib3/connectionpool.py", line 440, in _make_request httplib_response = conn.getresponse() File "/usr/lib64/python3.6/http/client.py", line 1346, in getresponse response.begin() File "/usr/lib64/python3.6/http/client.py", line 307, in begin version, status, reason = self._read_status() File "/usr/lib64/python3.6/http/client.py", line 276, in _read_status raise RemoteDisconnected("Remote end closed connection without" urllib3.exceptions.ProtocolError: ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response',)) During handling of the above exception, another exception occurred: Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/prog/res/komodo/2021.08.03-py36-rhel7/root/lib/python3.6/site-packages/requests/api.py", line 119, in post return request('post', url, data=data, json=json, **kwargs) File "/prog/res/komodo/2021.08.03-py36-rhel7/root/lib/python3.6/site-packages/requests/api.py", line 61, in request return session.request(method=method, url=url, **kwargs) File "/prog/res/komodo/2021.08.03-py36-rhel7/root/lib/python3.6/site-packages/requests/sessions.py", line 542, in request resp = self.send(prep, **send_kwargs) File "/prog/res/komodo/2021.08.03-py36-rhel7/root/lib/python3.6/site-packages/requests/sessions.py", line 655, in send r = adapter.send(request, **kwargs) File "/prog/res/komodo/2021.08.03-py36-rhel7/root/lib/python3.6/site-packages/requests/adapters.py", line 498, in send raise ConnectionError(err, request=request) requests.exceptions.ConnectionError: ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response',))
Advertisement
Answer
RequestHandler
has an on_connection_close
method which is called when a connection is closed. You can override this to close the file object:
class UploadHandler(...): ... def on_connection_close(self): self.file.close()