# Buggy code
async def respond_with_responder(
    request, responder, media_type, file_size, upload_name=None
):
    """Responds to the request with given responder. If responder is None then
    returns 404.

    Args:
        request (twisted.web.http.Request)
        responder (Responder|None)
        media_type (str): The media/content type.
        file_size (int|None): Size in bytes of the media. If not known it should be None
        upload_name (str|None): The name of the requested file, if any.
    """
    if not responder:
        respond_404(request)
        return

    logger.debug("Responding to media request with responder %s", responder)
    add_file_headers(request, media_type, file_size, upload_name)
    try:
        with responder:
            await responder.write_to_consumer(request)
    except Exception as e:
        # The majority of the time this will be due to the client having gone
        # away. Unfortunately, Twisted simply throws a generic exception at us
        # in that case.
        logger.warning("Failed to write to consumer: %s %s", type(e), e)

        # Unregister the producer, if it has one, so Twisted doesn't complain
        if request.producer:
            request.unregisterProducer()

    finish_request(request)


# Traceback (AttributeError)
2019-05-31 11:55:56,270 - synapse.access.http.8008 - 233 - INFO - GET-1116745- 176.14.254.64 - 8008 - Received request: GET /_matrix/media/v1/thumbnail/amorgan.xyz/JpHpuDNOxuALIaPSENEAzZIu?width=800&amp;height=600
2019-05-31 11:55:56,273 - synapse.access.http.8008 - 302 - INFO - GET-1116745- 176.14.254.64 - 8008 - {None} Processed request: 0.003sec/-0.000sec (0.000sec, 0.000sec) (0.000sec/0.001sec/2) 92715B 200 "GET /_matrix/media/v1/thumbnail/amorgan.xyz/JpHpuDNOxuALIaPSENEAzZIu?width=800&amp;height=600 HTTP/1.0" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:67.0) Gecko/20100101 Firefox/67.0" [0 dbevts]
2019-05-31 11:55:56,321 - synapse.access.http.8008 - 233 - INFO - GET-1116746- 176.14.254.64 - 8008 - Received request: GET /_matrix/media/v1/thumbnail/amorgan.xyz/chzgDJfCkiDOFITyulcRWQOn?width=40&amp;height=40&amp;method=crop
2019-05-31 11:55:56,322 - synapse.http.site - 203 - WARNING - GET-1116746- Error processing request <XForwardedForRequest at 0x7feb7a25e860 method='GET' uri='/_matrix/media/v1/thumbnail/amorgan.xyz/chzgDJfCkiDOFITyulcRWQOn?width=40&amp;height=40&amp;method=crop' clientproto='HTTP/1.0' site=8008>: <class 'twisted.internet.error.ConnectionDone'> Connection was closed cleanly.
2019-05-31 11:55:56,325 - synapse.rest.media.v1._base - 192 - WARNING - GET-1116746- Failed to write to consumer: <class 'AttributeError'> 'NoneType' object has no attribute 'registerProducer'
2019-05-31 11:55:56,325 - synapse.http.server - 112 - ERROR - GET-1116746- Failed handle request via 'ThumbnailResource': <XForwardedForRequest at 0x7feb7a25e860 method='GET' uri='/_matrix/media/v1/thumbnail/amorgan.xyz/chzgDJfCkiDOFITyulcRWQOn?width=40&amp;height=40&amp;method=crop' clientproto='HTTP/1.0' site=8008>
Traceback (most recent call last):
File "/home/ops/.synapse3/env3/lib/python3.5/site-packages/twisted/internet/defer.py", line 1418, in _inlineCallbacks
result = g.send(result)
File "/home/ops/.synapse3/env3/lib/python3.5/site-packages/synapse/storage/_base.py", line 527, in runWithConnection
defer.returnValue(result)
File "/home/ops/.synapse3/env3/lib/python3.5/site-packages/twisted/internet/defer.py", line 1362, in returnValue
raise _DefGen_Return(val)
twisted.internet.defer._DefGen_Return: [{'thumbnail_width': 32, 'thumbnail_type': 'image/png', 'thumbnail_height': 32, 'thumbnail_length': 2341, 'thumbnail_method': 'crop'}, {'thumbnail_width': 239, 'thumbnail_type': 'image/png', 'thumbnail_height': 240, 'thumbnail_length': 84450, 'thumbnail_method': 'scale'}, {'thumbnail_width': 399, 'thumbnail_type': 'image/png', 'thumbnail_height': 400, 'thumbnail_length': 196365, 'thumbnail_method': 'scale'}, {'thumbnail_width': 96, 'thumbnail_type': 'image/png', 'thumbnail_height': 96, 'thumbnail_length': 16151, 'thumbnail_method': 'crop'}]

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/home/ops/.synapse3/env3/lib/python3.5/site-packages/twisted/internet/defer.py", line 1418, in _inlineCallbacks
result = g.send(result)
File "/home/ops/.synapse3/env3/lib/python3.5/site-packages/synapse/storage/_base.py", line 487, in runInteraction
defer.returnValue(result)
File "/home/ops/.synapse3/env3/lib/python3.5/site-packages/twisted/internet/defer.py", line 1362, in returnValue
raise _DefGen_Return(val)
twisted.internet.defer._DefGen_Return: [{'thumbnail_width': 32, 'thumbnail_type': 'image/png', 'thumbnail_height': 32, 'thumbnail_length': 2341, 'thumbnail_method': 'crop'}, {'thumbnail_width': 239, 'thumbnail_type': 'image/png', 'thumbnail_height': 240, 'thumbnail_length': 84450, 'thumbnail_method': 'scale'}, {'thumbnail_width': 399, 'thumbnail_type': 'image/png', 'thumbnail_height': 400, 'thumbnail_length': 196365, 'thumbnail_method': 'scale'}, {'thumbnail_width': 96, 'thumbnail_type': 'image/png', 'thumbnail_height': 96, 'thumbnail_length': 16151, 'thumbnail_method': 'crop'}]

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/home/ops/.synapse3/env3/lib/python3.5/site-packages/synapse/rest/media/v1/_base.py", line 187, in respond_with_responder
yield responder.write_to_consumer(request)
File "/home/ops/.synapse3/env3/lib/python3.5/site-packages/synapse/rest/media/v1/media_storage.py", line 263, in write_to_consumer
FileSender().beginFileTransfer(self.open_file, consumer)
File "/home/ops/.synapse3/env3/lib/python3.5/site-packages/twisted/protocols/basic.py", line 923, in beginFileTransfer
self.consumer.registerProducer(self, False)
File "/home/ops/.synapse3/env3/lib/python3.5/site-packages/twisted/web/http.py", line 961, in registerProducer
self.channel.registerProducer(producer, streaming)
AttributeError: 'NoneType' object has no attribute 'registerProducer'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/home/ops/.synapse3/env3/lib/python3.5/site-packages/synapse/http/server.py", line 81, in wrapped_request_handler
yield h(self, request)
File "/home/ops/.synapse3/env3/lib/python3.5/site-packages/synapse/rest/media/v1/thumbnail_resource.py", line 71, in _async_render_GET
request, media_id, width, height, method, m_type
File "/home/ops/.synapse3/env3/lib/python3.5/site-packages/synapse/rest/media/v1/thumbnail_resource.py", line 121, in _respond_local_thumbnail
yield respond_with_responder(request, responder, t_type, t_length)
File "/home/ops/.synapse3/env3/lib/python3.5/site-packages/twisted/internet/defer.py", line 1418, in _inlineCallbacks
result = g.send(result)
File "/home/ops/.synapse3/env3/lib/python3.5/site-packages/synapse/rest/media/v1/_base.py", line 196, in respond_with_responder
request.unregisterProducer()
File "/home/ops/.synapse3/env3/lib/python3.5/site-packages/twisted/web/http.py", line 967, in unregisterProducer
self.channel.unregisterProducer()
AttributeError: 'NoneType' object has no attribute 'unregisterProducer'
2019-05-31 11:55:56,326 - synapse.http.server - 415 - WARNING - GET-1116746- Not sending response to request <XForwardedForRequest at 0x7feb7a25e860 method='GET' uri='/_matrix/media/v1/thumbnail/amorgan.xyz/chzgDJfCkiDOFITyulcRWQOn?width=40&amp;height=40&amp;method=crop' clientproto='HTTP/1.0' site=8008>, already disconnected.
2019-05-31 11:55:56,326 - synapse.access.http.8008 - 302 - INFO - GET-1116746- 176.14.254.64 - 8008 - {None} Processed request: 0.005sec/-0.004sec (0.000sec, 0.000sec) (0.001sec/0.002sec/2) 0B 200! "GET /_matrix/media/v1/thumbnail/amorgan.xyz/chzgDJfCkiDOFITyulcRWQOn?width=40&amp;height=40&amp;method=crop HTTP/1.0" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:67.0) Gecko/20100101 Firefox/67.0" [0 dbevts]

# Fixed code
async def respond_with_responder(
    request, responder, media_type, file_size, upload_name=None
):
    """Responds to the request with given responder. If responder is None then
    returns 404.

    Args:
        request (twisted.web.http.Request)
        responder (Responder|None)
        media_type (str): The media/content type.
        file_size (int|None): Size in bytes of the media. If not known it should be None
        upload_name (str|None): The name of the requested file, if any.
    """
    if request._disconnected:
        logger.warning(
            "Not sending response to request %s, already disconnected.", request
        )
        return

    if not responder:
        respond_404(request)
        return

    logger.debug("Responding to media request with responder %s", responder)
    add_file_headers(request, media_type, file_size, upload_name)
    try:
        with responder:
            await responder.write_to_consumer(request)
    except Exception as e:
        # The majority of the time this will be due to the client having gone
        # away. Unfortunately, Twisted simply throws a generic exception at us
        # in that case.
        logger.warning("Failed to write to consumer: %s %s", type(e), e)

        # Unregister the producer, if it has one, so Twisted doesn't complain
        if request.producer:
            request.unregisterProducer()

    finish_request(request)