Reporting mid-stream errors to client with chunked Transfer-Encoding

243 views
Skip to first unread message

Josiah Ulfers

unread,
Sep 19, 2022, 2:25:26 PM9/19/22
to Tornado Web Server
Is there a recommended way of informing the client if an error happens at the server after writing headers with Transfer-Encoding: chunked? I believe the best approach is to catch errors and close the socket prematurely.

If uncaught in the Handler, Tornado logs "Cannot send error response after headers written," though it would be nice if it closed the stream without finishing the response. Are there downsides I don't see?

Example follows.

#!/usr/bin/env python3
import asyncio

import tornado
import tornado.web


class LateCrash(tornado.web.RequestHandler):

    async def write_crash(self):
        self.set_header('Content-Type', 'text/plain')
        self.set_header('Cache-Control', 'no-store')
        self.write('.')
        await self.flush()
        raise Exception('unexpected server error')

class Silent(LateCrash):  # client does not know there was an error

    async def get(self):
        await self.write_crash()

class Noisy(LateCrash):  # client sees incomplete transfer as error

    async def get(self):
        try:
            await self.write_crash()
        except:
            print('breaking connection')
            self.request.connection.stream.close()  # use exc_info=True?


async def main():
    app = tornado.web.Application([
        (r'/silent', Silent),
        (r'/noisy', Noisy),
    ])
    app.listen(8888)
    await asyncio.Event().wait()

if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())

Reply all
Reply to author
Forward
0 new messages