Problematic Recursion
So, I explained in my last post about how I used wrappers to make my code sleeker and whatnot. Well, there is a known "hitch" to wrappers, where if you're not careful and you store one in your database, all hell breaks loose. Some of you noticed my blog was down a lot lately. This is because every time I made an edit to any entry, the database would go bottoms up with an endless loop that would crash the application.
The way it would manifest is that I would fetch a wrapper, and ask it for one of its attributes. It goes and queries its inner object for the attribute, for transparency. That inner object is the wrapper itself, so it queries its inner object for the same attribute. So it queries its inner object for the attribute. So it queries its inner object for the attribute. So it queries its inner object for the attribute. So it queries its inner object for the attribute. Ad infinitum. Actually, not really, Python sensed an infinite recursion, so it crashed.
This had me stumped for a while, until today when ahamilto was standing over my shoulder and I was whining to him about my impenetrable bug. As always happens in a situation like this, I see the problem and make a fool of myself for not seeing it before.
The problem was this:
class EntryView(Viewbase): # ... def __init__(self, environ, session, extrapath): # ... self.entry = getEntry(self.entrykey) # ... def processEdit(self): # Method to process an edit into the database # ... # To ensure the entry is stored under the correct key, # delete it before changes, and re-add it after. del root['entries'][self.entry.key] self.entry.key = key self.entry.title = title self.entry.summary = summary self.entry.datatype = datatype self.entry.data = data self.entry.author = author root['entries'][key] = self.entry # ...
In the initialization of the EntryView object (which manages the rendering of all Entry-related pages) the entry attribute is initialized to the result of getEntry... which is a wsgiblog.storage.DBWrapper object. I later take that wrapped object, modify it, and store the object (still wrapped) inside the database with this bugged line:
root['entries'][key] = self.entry
To fix it? Just put the real object in (the entry)!
root['entries'][key] = self.entry._obj
Those 4 missing characters completely broke my blog. For programmers, small errors like this cause a facepalm and a moment of silence for their own stupidity. For the end user, this can mean frustration over blue screens (or in my case, "Internal server error" messages).