是什么导致了这个回溯?
我在本地和生产环境中提交表单时遇到了以下错误信息。你能告诉我应该从哪里入手,或者我应该开始添加调试语句,看看代码中异常发生在哪里吗?
--> --> -->
Traceback (most recent call last):
File "/media/Lexar/montao/google/appengine/tools/dev_appserver.py", line 3858, in _HandleRequest
self._Dispatch(dispatcher, self.rfile, outfile, env_dict)
File "/media/Lexar/montao/google/appengine/tools/dev_appserver.py", line 3792, in _Dispatch
base_env_dict=env_dict)
File "/media/Lexar/montao/google/appengine/tools/dev_appserver.py", line 580, in Dispatch
base_env_dict=base_env_dict)
File "/media/Lexar/montao/google/appengine/tools/dev_appserver.py", line 2918, in Dispatch
self._module_dict)
File "/media/Lexar/montao/google/appengine/tools/dev_appserver.py", line 2822, in ExecuteCGI
reset_modules = exec_script(handler_path, cgi_path, hook)
File "/media/Lexar/montao/google/appengine/tools/dev_appserver.py", line 2704, in ExecuteOrImportScript
script_module.main()
File "/media/Lexar/montao/classifiedsmarket/main.py", line 2497, in main
util.run_wsgi_app(application)
File "/media/Lexar/montao/google/appengine/ext/webapp/util.py", line 98, in run_wsgi_app
run_bare_wsgi_app(add_wsgi_middleware(application))
File "/media/Lexar/montao/google/appengine/ext/webapp/util.py", line 116, in run_bare_wsgi_app
result = application(env, _start_response)
File "/media/Lexar/montao/google/appengine/ext/webapp/__init__.py", line 655, in __call__
response.wsgi_write(start_response)
File "/media/Lexar/montao/google/appengine/ext/webapp/__init__.py", line 274, in wsgi_write
body = self.out.getvalue()
File "/usr/lib/python2.6/StringIO.py", line 270, in getvalue
self.buf += ''.join(self.buflist)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 3: ordinal not in range(128)
1 个回答
5
这个错误出现在/usr/lib/python2.6/StringIO.py文件里,也就是Python的StringIO模块。我们不需要深入研究这个文件(第49行)就能找到这个警告:
The StringIO object can accept either Unicode or 8-bit strings, but mixing the two may take some care. If both are used, 8-bit strings that cannot be interpreted as 7-bit ASCII (that use the 8th bit) will cause a UnicodeError to be raised when getvalue() is called.
太好了!这个警告在getvalue()方法中又出现了一次。注意,这个警告是很久以前的;它提到的是UnicodeError,而不是UnicodeDecodeError,但大致意思是一样的。
我建议你修改这个模块,让它在出错时显示出错误发生时的内容。把第270行的有问题的代码包裹起来,像这样:
if self.buflist:
try:
self.buf += ''.join(self.buflist)
except UnicodeDecodeError:
import sys
print >> sys.stderr, "*** error context: buf=%r buflist=%r" % (self.buf, self.buflist)
raise
self.buflist = []
return self.buf
如果你觉得直接修改Python自带的模块让你感到不安,可以把修改后的版本放在一个比/usr/lib/python2.6
更靠前的目录中,这样Python会优先使用你的版本。
这里有一个混合使用非ASCII的str
和unicode
的例子:
>>> from StringIO import StringIO
>>> f = StringIO()
>>> f.write('ascii')
>>> f.write(u'\u1234'.encode('utf8'))
>>> f.write(u'\u5678')
>>> f.getvalue()
*** error context: buf='' buflist=['ascii', '\xe1\x88\xb4', u'\u5678']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\python26\lib\StringIO.py", line 271, in getvalue
self.buf += ''.join(self.buflist)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe1 in position 0: ordinal not in range(128)
>>>
然后你可以运行你的应用程序,查看buflist
里的内容:哪些是你写入的数据,哪些是GAE提供的。你需要查看GAE的文档,看看它是期待str
类型的内容(用什么编码?)还是unicode
类型的内容,并相应地调整你的代码。