The built-in ticketing mechanism is a last resort error. You should catch exceptions in your own app. Anyway, the following decorator may be helpful:
def onerror(function):
def __onerror__(*a,**b):
try:
return function(*a,**b)
except HTTP, e:
import os
status=int(e.status.split(' ')[0])
filename=os.path.join(request.folder,'views/onerror%i.html'%status)
if os.access(filename,os.R_OK):
e.body=open(filename,'r').read()
raise e
except Exception:
import os, gluon.restricted
e=gluon.restricted.RestrictedError(function.__name__)
SQLDB.close_all_instances(SQLDB.rollback)
ticket=e.log(request)
filename=os.path.join(request.folder,'views/onerror.html')
if os.access(filename,os.R_OK):
body=open(filename,'r').read()
else:
body="""<html><body><h1>Internal error</h1>Ticket issued:
<a href="/admin/default/ticket/%(ticket)s" target="_blank">%(ticket)s</a></body></html>"""
body=body % dict(ticket=ticket)
raise HTTP(200,body=body)
return __onerror__
There is how you use:
Put the function above in a place where it is accessible (a model file for example)
Consider any function in a model a controller or a view that you where you want to use custom error pages and do
@onerror
def index:
...
now if the index controller function raises an HTTP(400,...) it will be rendered by views/onerror400.html if the index controller function raises any other exception, it will be rendered by views/onerror.html
Notice that onerrorXXX.html and onerror.html must be static HTML files and are not processed as templates. onerror.HTML can contain "%(ticket)s" in order to refer to the ticket being issued.
Here is an example of an error400.html page
<html><body><h1>Internal Error</h1></body></html>
Here is an example of an error.html page
<html><body><h1>Hey dude, here is your ticket: %(ticket)s</h1></body></html>