##################################################
# SPYCE - Python-based HTML Scripting
# Copyright (c) 2002 Rimon Barr.
#
# Refer to spyce.py
# CVS: $Id: error.py 578 2005-04-19 04:09:33Z jbe $
##################################################
from spyceModule import spyceModule
import spyceException, spyceUtil
import os
__doc__ = '''Error module provides error-handling functionality.'''
class error(spyceModule):
def start(self):
self._error = None
pageerrorType, pageerrorData = self._api.getPageError()
self.handler = lambda self, pageerrorType=pageerrorType, pageerrorData=pageerrorData: spyceHandler(self, pageerrorData, pageerrorType)
def finish(self, theError=None):
self._error = theError
self._fromFile = self._api.getFilename()
if theError:
self.handler(self)
def setHandler(self, fn):
if not type(fn)==type(spyceHandler):
raise 'parameter should be a function'
self.handler = fn
def setStringHandler(self, s):
if not type(s)==type(''):
raise 'parameter should be a string of spyce code'
self.handler = lambda self, s=s: spyceHandler(self, s, 'string')
def setFileHandler(self, f):
if not type(f)==type(''):
raise 'parameter should be a filename'
self.handler = lambda self, f=f: spyceHandler(self, f)
def getHandler(self):
return self.handler
def isError(self):
return not not self._error
def getMessage(self):
if self._error: return self._error.msg
def getType(self):
if self._error: return self._error.type
def getFile(self):
if self._error: return self._fromFile
def getTraceback(self):
if self._error: return self._error.traceback
def getString(self):
if self._error: return self._error.str
def __repr__(self):
if not self._error: return 'None'
return 'type: %s, string: %s, msg: %s, file: %s' % (
self.getType(), self.getString(), self.getMessage(), self.getFile())
def spyceHandler(errorModule, spyceCode, type='file'):
try:
responseModule = errorModule._api.getModule('response')
responseModule.clear()
responseModule.clearHeaders()
responseModule.clearFilters()
responseModule.setContentType('text/html')
responseModule.setReturnCode(errorModule._api.getResponse().RETURN_OK)
except: pass
try:
s, file = None, None
if type=='file':
file = spyceUtil.url2file(spyceCode, errorModule._api.getFilename())
code = errorModule._api.spyceFile(file)
elif type=='string':
file = '<string>'
code = errorModule._api.spyceString(spyceCode)
else:
raise 'unrecognized handler type'
try:
s = code.newWrapper()
modules = errorModule._api.getModules()
for name in modules.keys():
s.setModule(name, modules[name]) # include modules as well!
s.spyceInit(errorModule._api.getRequest(), errorModule._api.getResponse())
errmod = s._startModule('error', None, None, 1)
errmod._error = errorModule._error
errmod._fromFile = errorModule._fromFile
s.spyceProcess()
finally:
if s:
s.spyceDestroy()
code.returnWrapper(s)
except spyceException.spyceRuntimeException, e:
errorModule._error = e
errorModule._fromFile = file
if (type, spyceCode) == ('string', defaultErrorTemplate):
raise # avoid infinite loop
else:
spyceHandler(errorModule, defaultErrorTemplate, 'string')
defaultErrorTemplate = r'''
[[.module name=transform]]
[[transform.expr('html_encode')]]
<html>
<title>Spyce exception: [[=error.getMessage()]]</title>
<body>
<table cellspacing=10 border=0>
<tr><td colspan=2><h1>Spyce exception</h1></td></tr>
<tr><td valign=top align=right><b>File:</b></td><td>[[=error.getFile()]]</tr>
<tr><td valign=top align=right><b>Message:</b></td>
<td><pre>[[=error.getMessage()]]</pre></tr>
<tr><td valign=top align=right><b>Stack:</b></td><td>
[[\
L = list(error.getTraceback())
L.reverse()
]]
[[ for frame in L: { ]]
[[=frame[0] ]]:[[=frame[1] ]], in [[=frame[2] ]]:<br>
<table border=0><tr><td width=10></td><td>
<pre>[[=frame[3] ]]</pre>
</td></tr></table>
[[ } ]]
</td></tr>
</table>
</body></html>
'''
def serverHandler(theServer, theRequest, theResponse, theError):
try:
theResponse.clear()
theResponse.clearHeaders()
theResponse.setContentType('text/html')
theResponse.setReturnCode(theResponse.RETURN_OK)
except: pass
s = None
try:
spycecode = theServer.spyce_cache[('string', serverErrorTemplate)]
s = spycecode.newWrapper()
s.spyceInit(theRequest, theResponse)
s.getModule('error')._error = theError
s.spyceProcess()
finally:
if s:
s.spyceDestroy()
spycecode.returnWrapper(s)
serverErrorTemplate = '''
[[.module name=transform]]
[[import string, spyceException
if isinstance(error._error, spyceException.spyceNotFound): { ]]
<html><body>
[[=error._error.file]] not found
[[response.setReturnCode(response._api.getResponse().RETURN_NOT_FOUND)]]
</body></html>
[[ } elif isinstance(error._error, spyceException.spyceForbidden): { ]]
<html><body>
[[=error._error.file]] forbidden
[[response.setReturnCode(response._api.getResponse().RETURN_FORBIDDEN)]]
</body></html>
[[ } elif isinstance(error._error, spyceException.spyceSyntaxError): { ]]
<html><body><pre>
[[=transform.html_encode(`error._error`)]]
</pre></body></html>
[[ } elif isinstance(error._error, spyceException.pythonSyntaxError): { ]]
<html><body><pre>
[[=transform.html_encode(`error._error`)]]
</pre></body></html>
[[ } elif isinstance(error._error, SyntaxError): { ]]
<html><body><pre>
Syntax error at [[=error._error.filename]]:[[=error._error.lineno]] -
[[=transform.html_encode(error._error.text)]] [[
if not error._error.offset==None: {
print ' '*error._error.offset+'^'
}
]]
</pre></body></html>
[[ } else: { raise error._error } ]]
'''
|