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'
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'