japronto icon indicating copy to clipboard operation
japronto copied to clipboard

Request.Response can only be called once per request

Open agalera opened this issue 8 years ago • 5 comments

If an exception is generated in the response this error appears and the request is blocked

from japronto import Application


app = Application()

def hello(request):
    request.Response(json=['invalid', 'json'])

app.router.add_route(url, hello, method='GET')
app.run()
ValueError: View did not return Response instance
Unhandled exception in event loop
Traceback (most recent call last):
  File "uvloop/handles/stream.pyx", line 785, in uvloop.loop.__uv_stream_on_read_impl (uvloop/loop.c:76261)
  File "uvloop/handles/stream.pyx", line 559, in uvloop.loop.UVStream._on_read (uvloop/loop.c:73525)
  File "/root/japronto-env/lib/python3.6/site-packages/japronto/app/__init__.py", line 99, in error_handler
    return self.default_error_handler(request, exception)
  File "/root/japronto-env/lib/python3.6/site-packages/japronto/app/__init__.py", line 81, in default_error_handler
    text=tb if self._debug else 'Internval Server Error')

agalera avatar Jan 31 '17 23:01 agalera

def hello(request):
    return request.Response(json=['invalid', 'json'])

ilia-khaustov avatar Feb 01 '17 17:02 ilia-khaustov

Is voluntary, a valid json is always a dict, here fails to make the conversion to json.

agalera avatar Feb 01 '17 17:02 agalera

It's a wart in the API design, I need to refactor this part. What is happening here is that an error is generated in an error handler and since request.Response was already constructed and it's immutable. It fails in a weird way swallowing the real reason.

So this is really about making Response mutable.

squeaky-pl avatar Feb 01 '17 18:02 squeaky-pl

@kianxineki The error doesnt happen because of invalid JSON. Python JSON module will happily transform a list in a JSON array. I don't impose any extra restrictions here. This happens because of missing return.

Anyway this is an error and needs to be fixed.

squeaky-pl avatar Feb 01 '17 18:02 squeaky-pl

Finally figured out what it is all about.

from japronto import Application

app = Application()

def hello(request):
    try:
        return request.Response(json=object())
    except TypeError:
        return request.Response(code=500)  # RuntimeError due to immutable Response

app.router.add_route('/', hello, method='GET')
app.run()

ilia-khaustov avatar Feb 01 '17 18:02 ilia-khaustov