1

I have this code, which used to work before upgrading GAE Python NDB:

class MyHandler(webapp2.RequestHandler):
  def get(self,urlString):
    resume = ndb.Key(urlsafe=urlString).get()

Now, I have this error:

Traceback (most recent call last):
  File "C:\Program Files (x86)\Google\google_appengine\lib\webapp2-2.5.2\webapp2.py", line 1535, in __call__
    rv = self.handle_exception(request, response, e)
  File "C:\Program Files (x86)\Google\google_appengine\lib\webapp2-2.5.2\webapp2.py", line 1529, in __call__
    rv = self.router.dispatch(request, response)
  File "C:\Program Files (x86)\Google\google_appengine\lib\webapp2-2.5.2\webapp2.py", line 1278, in default_dispatcher
    return route.handler_adapter(request, response)
  File "C:\Program Files (x86)\Google\google_appengine\lib\webapp2-2.5.2\webapp2.py", line 1102, in __call__
    return handler.dispatch()
  File "C:\Program Files (x86)\Google\google_appengine\lib\webapp2-2.5.2\webapp2.py", line 572, in dispatch
    return self.handle_exception(e, self.app.debug)
  File "C:\Program Files (x86)\Google\google_appengine\lib\webapp2-2.5.2\webapp2.py", line 570, in dispatch
    return method(*args, **kwargs)
  File "C:\xampp\htdocs\mapjobs\main.py", line 127, in get
    resume_key = ndb.Key(urlsafe=urlString)
  File "C:\Program Files (x86)\Google\google_appengine\google\appengine\ext\ndb\key.py", line 212, in __new__
    self.__reference = _ConstructReference(cls, **kwargs)
  File "C:\Program Files (x86)\Google\google_appengine\google\appengine\ext\ndb\utils.py", line 136, in positional_wrapper
    return wrapped(*args, **kwds)
  File "C:\Program Files (x86)\Google\google_appengine\google\appengine\ext\ndb\key.py", line 642, in _ConstructReference
    reference = _ReferenceFromSerialized(serialized)
  File "C:\Program Files (x86)\Google\google_appengine\google\appengine\ext\ndb\key.py", line 774, in _ReferenceFromSerialized
    return entity_pb.Reference(serialized)
  File "C:\Program Files (x86)\Google\google_appengine\google\appengine\datastore\entity_pb.py", line 1791, in __init__
    if contents is not None: self.MergeFromString(contents)
  File "C:\Program Files (x86)\Google\google_appengine\google\net\proto\ProtocolBuffer.py", line 84, in MergeFromString
    self.MergePartialFromString(s)
  File "C:\Program Files (x86)\Google\google_appengine\google\net\proto\ProtocolBuffer.py", line 98, in MergePartialFromString
    self.TryMerge(d)
  File "C:\Program Files (x86)\Google\google_appengine\google\appengine\datastore\entity_pb.py", line 1920, in TryMerge
    d.skipData(tt)
  File "C:\Program Files (x86)\Google\google_appengine\google\net\proto\ProtocolBuffer.py", line 524, in skipData
    self.skip(4)
  File "C:\Program Files (x86)\Google\google_appengine\google\net\proto\ProtocolBuffer.py", line 499, in skip
    if self.idx + n > self.limit: raise ProtocolBufferDecodeError, "truncated"
ProtocolBufferDecodeError: truncated

Which the highlight could be:

File "C:\Program Files (x86)\Google\google_appengine\lib\webapp2-2.5.2\webapp2.py", line 570, in dispatch
  return method(*args, **kwargs)
File "C:\xampp\htdocs\mapjobs\main.py", line 127, in get
  resume_key = ndb.Key(urlsafe=urlString)

What's wrong?

Chris Martin
  • 30,334
  • 10
  • 78
  • 137
Franz Noel
  • 1,820
  • 2
  • 23
  • 50

2 Answers2

3

My guess is that you are receiving key as a url safe string via a Url parameter, which gets truncated due to max Url length limit in browsers. Browsers in practice limit Url length to max 2000 chars. See this question: What is the maximum length of a URL in different browsers?

If your key contains (multiple) parent keys, then it's possible to go over 2000 chars. Is this the case? Pls check the length of urlsafe-encoded key when created and when received.

If this is the case, then the workaround would be to just use ID of the entity (or entities in case of parent keys) and construct the key by hand.

Community
  • 1
  • 1
Peter Knego
  • 79,991
  • 11
  • 123
  • 154
  • I think I got it now. I misarranged the webapp2 receiver. I'm referring to the '/resume/(.*)'. I'll post my answer, just a second. This could also be a possibility, though. Thanks. – Franz Noel Oct 23 '13 at 07:15
0

I mismatched the url, where before:

app = webapp2.WSGIApplication([
    ('/', MainHandler),
    ('/jobs',JobsHandler),
    ('/job/(.*)',JobHandler),
    ('/job/(.*)/update', JobUpdateHandler),
    ('/job/(.*)/delete', JobDeleteHandler),
    ('/job/create', JobCreateHandler),
    ('/resume/(.*)',ResumeHandler),
    ('/resume/(.*)/update', ResumeUpdateHandler),
    ('/resume/(.*)/delete', ResumeDeleteHandler),
    ('/resume/create', ResumeCreateHandler),
    ('/resumes',ResumesHandler),
    ('/profile',ProfileHandler),
    ('/profile/(.*)/update', ProfileUpdateHandler),
], debug=True)

Notice that I misarranged '/resume/(.*)', because this should be at the bottom to receive the urlString last. Here's what it is now:

app = webapp2.WSGIApplication([
    ('/', MainHandler),
    ('/jobs',JobsHandler),
    ('/job/(.*)/update', JobUpdateHandler),
    ('/job/(.*)/delete', JobDeleteHandler),
    ('/job/create', JobCreateHandler),
    ('/job/(.*)',JobHandler),
    ('/resume/(.*)/update', ResumeUpdateHandler),
    ('/resume/(.*)/delete', ResumeDeleteHandler),
    ('/resume/create', ResumeCreateHandler),
    ('/resume/(.*)',ResumeHandler),
    ('/resumes',ResumesHandler),
    ('/profile',ProfileHandler),
    ('/profile/(.*)/update', ProfileUpdateHandler),
], debug=True)
Franz Noel
  • 1,820
  • 2
  • 23
  • 50
  • I somehow solved this before, but there are some things that I mislook because of over thinking. So, I think it is good that I have this as a note to myself. I hope the error message can be more visible. – Franz Noel Oct 23 '13 at 07:11
  • I can see how the url order would have prevented you from reaching the create/update/delete handlers... I don't see how this could have fixed your ProtocolBufferDecodeError though? – Anentropic Oct 21 '14 at 11:20
  • I do not know either, to be honest, but it just fixed it. Something to do in error handling, I guess. Maybe... – Franz Noel Nov 07 '14 at 05:28