ahopkins/sanic-session

"NoneType has no attribute cookies" with websockets

garyo opened this issue · 2 comments

garyo commented

I think websocket requests in Sanic don't have responses (they're long-lived); so when I add a sanic-session session it tries to save cookies for the websocket requests as well, which gives the error above. It works better for me if I check for response being None in base.py _set_cookie_expiration.

xen commented

Can you provide code or full error message?

garyo commented

Here's the error and traceback:

09:09:39 52006 [sanic.error] ERROR  Exception occurred in one of response middleware handlers
Traceback (most recent call last):
  File "/Users/garyo/.local/share/virtualenvs/shorelight-director/lib/python3.6/site-packages/sanic/app.py", line 628, in handle_request
    response)
  File "/usr/local/Cellar/python3/3.6.4_2/Frameworks/Python.framework/Versions/3.6/lib/python3.6/asyncio/coroutines.py", line 110, in __next__
    return self.gen.send(None)
  File "/Users/garyo/.local/share/virtualenvs/shorelight-director/lib/python3.6/site-packages/sanic/app.py", line 791, in _run_response_middleware
    _response = await _response
  File "/usr/local/Cellar/python3/3.6.4_2/Frameworks/Python.framework/Versions/3.6/lib/python3.6/asyncio/coroutines.py", line 110, in __next__
    return self.gen.send(None)
  File "/Users/garyo/.local/share/virtualenvs/shorelight-director/lib/python3.6/site-packages/sanic_session/__init__.py", line 42, in save_session
    await self.interface.save(request, response)
  File "/usr/local/Cellar/python3/3.6.4_2/Frameworks/Python.framework/Versions/3.6/lib/python3.6/asyncio/coroutines.py", line 110, in __next__
    return self.gen.send(None)
  File "/Users/garyo/.local/share/virtualenvs/shorelight-director/lib/python3.6/site-packages/sanic_session/base.py", line 136, in save
    self._set_cookie_expiration(request, response)
  File "/Users/garyo/.local/share/virtualenvs/shorelight-director/lib/python3.6/site-packages/sanic_session/base.py", line 36, in _set_cookie_expiration
    response.cookies[self.cookie_name] = request['session'].sid
AttributeError: 'NoneType' object has no attribute 'cookies'

And here's a patch that makes it work:

    def _set_cookie_expiration(self, request, response):
+        if not response:
+            print(f'Trying to run response middleware for {request} with no response')
+            return
        response.cookies[self.cookie_name] = request['session'].sid
        response.cookies[self.cookie_name]['httponly'] = self.httponly