Extreme Yaro weirdness

R

Ron Garret

I'm running the following WSGI app under Yaro:

def error(req):
try:
req.non_existent_key
except:
try:
return cgitb.html(sys.exc_info())
except:
return 'foo'

The result of running this is 'foo'. In other words, the reference to
the non-existent key generates an exception as expected, but then the
generation of the traceback generates ANOTHER exception, which I would
not have expected. If I add another TRY/EXCEPT block to capture this
exception, the result is attached at the bottom of this message.

It gets better.

I get the same result whether I run under Apache/mod_wsgi or standalone
using wsgi_ref. But if I add the following code to try to capture a
Yaro request object so I can noodle around with it:


def error(req):
global req1
req1=req
try: ...


it makes the problem go away! But it ONLY makes the problem go away
when running under wsgi_ref, not under Apache!

The problem seems to be specific to Yaro. If I make an instance of an
object and try to dereference a non-existent attribute, the initial
traceback gets generated with no problem. Also, the Yaro code for
Request.__getattr__ ultimately calls req.__dict__[attr]. If I make this
call directly, the problem also goes away.

I am quite baffled by this. Any suggestions on how to debug this would
be much appreciated.

Thanks,
rg


----


<type 'exceptions.KeyError'>
Python 2.5: /usr/local/bin/python
Mon Feb 2 00:54:33 2009

A problem occurred in a Python script. Here is the sequence of
function calls leading up to the error, in the order they occurred.

/www/sites/mcia.cc/files/wsgi/test.wsgi in error(req=<yaro.Request
object at 0x2aaaab94a690>)
212 except:
213 try:
214 return cgitb.text(sys.exc_info())
215 except:
216 try:
global cgitb = <module 'cgitb' from '/usr/lib/python2.5/cgitb.pyc'>
cgitb.text = <function text at 0x2aaaab0adc80>
global sys = <module 'sys' (built-in)>
sys.exc_info = <built-in function exc_info>

/www/sites/cgitb.py in text((etype=<type 'exceptions.KeyError'>,
evalue=KeyError('non_existent_key',), etb=<traceback object at
0x2aaaab960368>), context=5)
215 try: return linecache.getline(file, lnum[0])
216 finally: lnum[0] += 1
217 vars = scanvars(reader, frame, locals)
218
219 rows = [' %s %s' % (file, call)]
builtinvars = <built-in function vars>
global scanvars = <function scanvars at 0x2aaaab0adb90>
reader = <function reader at 0x2aaaabbbea28>
frame = <frame object at 0xba49e0>
locals = {'req': <yaro.Request object at 0x2aaaab94a690>}

/www/sites/cgitb.py in scanvars(reader=<function reader at
0x2aaaabbbea28>, frame=<frame object at 0xba49e0>, locals={'req':
<yaro.Request object at 0x2aaaab94a690>})
82 if lasttoken == '.':
83 if parent is not __UNDEF__:
84 value = getattr(parent, token, __UNDEF__)
85 vars.append((prefix + token, prefix, value))
86 else:
value = <yaro.Request object at 0x2aaaab94a690>
builtingetattr = <built-in function getattr>
parent = <yaro.Request object at 0x2aaaab94a690>
token = 'non_existent_key'
__UNDEF__ undefined

/www/sites/mcia.cc/files/wsgi/yaro.py in __getattr__(self=<yaro.Request
object at 0x2aaaab94a690>, attr='non_existent_key')
215 elif attr == 'cookie' and not 'cookie' in self.__dict__:
216 self._load_cookie()
217 return self.__dict__[attr]
218
219 def _parse_query(self):
self = <yaro.Request object at 0x2aaaab94a690>
self.__dict__ = {'_start_response': <built-in method start_response of
mod_wsgi.Adapter object at 0x2aaaaab218a0>, 'content_length': '',
'content_type': '', 'environ': {'DOCUMENT_ROOT':
'/www/sites/mcia.cc/html', 'GATEWAY_INTERFACE': 'CGI/1.1',
'HTTP_ACCEPT':
'text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plai
n;q=0.8,image/png,*/*;q=0.5', 'HTTP_ACCEPT_ENCODING': 'gzip, deflate',
'HTTP_ACCEPT_LANGUAGE': 'en-us', 'HTTP_CACHE_CONTROL': 'max-age=0',
'HTTP_CONNECTION': 'keep-alive', 'HTTP_COOKIE': 'sid=55UGS64T',
'HTTP_HOST': 'mcia.cc', 'HTTP_REFERER': 'http://mcia.cc/wtest/menu',
....}, 'exc_info': None, 'extra_props': None, 'method': 'GET', 'query':
{}, 'res': <yaro.Response object at 0x2aaaab94a710>,
'start_response_called': False, ...}
attr = 'non_existent_key'
<type 'exceptions.KeyError'>: 'non_existent_key'

The above is a description of an error in a Python program. Here is
the original traceback:

Traceback (most recent call last):
File "/www/sites/mcia.cc/files/wsgi/test.wsgi", line 214, in error
return cgitb.text(sys.exc_info())
File "cgitb.py", line 217, in text
vars = scanvars(reader, frame, locals)
File "cgitb.py", line 84, in scanvars
value = getattr(parent, token, __UNDEF__)
File "/www/sites/mcia.cc/files/wsgi/yaro.py", line 217, in __getattr__
return self.__dict__[attr]
KeyError: 'non_existent_key'
 
G

Gabriel Genellina

I'm running the following WSGI app under Yaro:

def error(req):
try:
req.non_existent_key
except:
try:
return cgitb.html(sys.exc_info())
except:
return 'foo'

The result of running this is 'foo'. In other words, the reference to
the non-existent key generates an exception as expected, but then the
generation of the traceback generates ANOTHER exception, which I would
not have expected. If I add another TRY/EXCEPT block to capture this
exception, the result is attached at the bottom of this message.

Unqualified excepts are evil -- see this recent post (mine)
http://groups.google.com/group/comp.lang.python/msg/05e822f694b6421c

But in this case you hit a known bug in cgitb - see
http://bugs.python.org/issue4643 for a solution.
 
R

Ron Garret

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,968
Messages
2,570,149
Members
46,695
Latest member
StanleyDri

Latest Threads

Top