joerussbowman / gaeutilities

gaeutilities - A collection of utilities to help with application development on Google Appengine
http://gaeutilities.appspot.com
BSD 3-Clause "New" or "Revised" License
78 stars 4 forks source link

Exception: BadKeyError: Invalid string key #23

Closed e2jk closed 14 years ago

e2jk commented 14 years ago

I am using gaeutilities for some months now, and have never seen this error yet. I haven't changed anything in the last week, and 2 days ago (lat time I logged in) everything was working fine. But now I try to log in and I directly get this exception:

Traceback (most recent call last):
    File "/base/python_runtime/python_lib/versions/1/google/appengine/ext/webapp/__init__.py", line 511, in __call__
      handler.get(*groups)
    File "/base/data/home/apps/colombiacasacom/40.342414516289222802/src/decorators.py", line 87, in wrapper
      self.session = Session()
    File "/base/data/home/apps/colombiacasacom/40.342414516289222802/lib/appengine_utilities/sessions.py", line 562, in __init__
      self.session = _AppEngineUtilities_Session.get_session(self)
    File "/base/data/home/apps/colombiacasacom/40.342414516289222802/lib/appengine_utilities/sessions.py", line 142, in get_session
      ds_session = db.get(str(session_key))
    File "/base/python_runtime/python_lib/versions/1/google/appengine/ext/db/__init__.py", line 1243, in get
      keys, multiple = datastore.NormalizeAndTypeCheckKeys(keys)
    File "/base/python_runtime/python_lib/versions/1/google/appengine/api/datastore.py", line 150, in NormalizeAndTypeCheckKeys
      keys = [_GetCompleteKeyOrError(key) for key in keys]
    File "/base/python_runtime/python_lib/versions/1/google/appengine/api/datastore.py", line 2400, in _GetCompleteKeyOrError
      key = Key(arg)
    File "/base/python_runtime/python_lib/versions/1/google/appengine/api/datastore_types.py", line 273, in __init__
      raise datastore_errors.BadKeyError('Invalid string key %s.' % encoded)
  BadKeyError: Invalid string key ag9jb2xvbWJpYWNhc2Fjb21yIwsSG19BcHBFbmdpbmVVdGlsaXRpZXNfU2Vzc2lvbhiq.

Could this be due to the fact that you are passing a string to db.get, when the docs say that it shoudl be a Key object?

Or could this be due to an old Session being stored in the datastore?

Anyways, this should not generate this unhandled exception visible to the end user. I guess that if the db.get fails, the user should just not be logged in and don't see the exception... Any thoughts?

e2jk commented 14 years ago

Apparently this happened because I still had the cookie in my browser while the datastore had no such entity. Deleting the cookie in the browser enabled me to continue, but this still doesn't fix the issue that the session should not error out like this. I will investigate putting this db.get call in an except block.

e2jk commented 14 years ago

Also, in order to see this bug the session must not be in memcached. So the conditions are:

joerussbowman commented 14 years ago

they are inducing my wife on tuesday, not sure when i will have time to look at this.

bdoms commented 14 years ago

I actually just encountered this today on a live app. Good to know that there's a workaround (telling the user seeing the problem to delete their cookies).

I think the fastest solution would be to just put a try/except around the offending part:

--- a/sessions.py
+++ b/sessions.py
@@ -138,8 +138,10 @@ class _AppEngineUtilities_Session(db.Model):
                 return None

         # Not in memcache, check datastore
-        
-        ds_session = db.get(str(session_key))
+        try:
+            ds_session = db.get(str(session_key))
+        except:
+            ds_session = None
         if ds_session:
           sessionAge = datetime.datetime.now() - ds_session.last_activity
           if sessionAge.seconds > session_obj.session_expire_time:

But there's probably a more elegant solution.

joerussbowman commented 14 years ago

I used the patch above, put it in via the web interface. Grab the master branch and you should be good. I'll see about getting a release rolled up, but as my daughter was born last night I have other priorities at the moment.

AlexzAK commented 13 years ago

I'am affected by this bug :(

:     session = gaeutilities.sessions.Session()
:   File "/base/data/home/apps/odelis-net/1.350624512923347810/odelis/gaeutilities/sessions.py", line 562, in __init__
:     self.session = _AppEngineUtilities_Session.get_session(self)
:   File "/base/data/home/apps/odelis-net/1.350624512923347810/odelis/gaeutilities/sessions.py", line 142, in get_session
:     ds_session = db.get(str(session_key))
:   File "/base/python_runtime/python_lib/versions/1/google/appengine/ext/db/__init__.py", line 1471, in get
:     return get_async(keys, **kwargs).get_result()
:   File "/base/python_runtime/python_lib/versions/1/google/appengine/ext/db/__init__.py", line 1430, in get_async
:     keys, multiple = datastore.NormalizeAndTypeCheckKeys(keys)
:   File "/base/python_runtime/python_lib/versions/1/google/appengine/api/datastore.py", line 180, in NormalizeAndTypeCheckKeys
:     keys = [_GetCompleteKeyOrError(key) for key in keys]
:   File "/base/python_runtime/python_lib/versions/1/google/appengine/api/datastore.py", line 2409, in _GetCompleteKeyOrError
:     key = Key(arg)
:   File "/base/python_runtime/python_lib/versions/1/google/appengine/api/datastore_types.py", line 364, in __init__
:     raise datastore_errors.BadKeyError('Invalid string key %s.' % encoded)
: BadKeyError: Invalid string key agpvZGVsaXMtbmV0ciMLEhtfQXBwRW5naW5lVXRpbGl0aWVzX1Nlc3Npb24Y.