Cache the target argspec in formparams.
[wrw.git] / wrw / dispatch.py
1 import sys, traceback
2 import env, req, proto
3
4 __all__ = ["restart"]
5
6 class restart(Exception):
7     def handle(self, req):
8         pass
9
10 def mangle(result):
11     try:
12         iter(result)
13     except TypeError:
14         pass
15     else:
16         return result
17     return [str(result)]
18
19 def defaulterror(req, excinfo):
20     import resp
21     traceback.print_exception(*excinfo)
22     raise resp.httperror(500)
23
24 def wraphandler(handler, excinfo):
25     def wrapped(req):
26         return handler(req, excinfo)
27     wrapped.__wrapped__ = handler
28     return wrapped
29
30 errorhandler = env.var(defaulterror)
31
32 def handle(req, startreq, handler):
33     eh = errorhandler.val
34     try:
35         resp = [""]
36         while True:
37             try:
38                 resp = handler(req)
39                 break
40             except restart, i:
41                 handler = i.handle
42             except Exception, i:
43                 if eh is None:
44                     raise
45                 handler = wraphandler(eh, sys.exc_info())
46                 eh = None
47         req.commit(startreq)
48         return resp
49     finally:
50         req.cleanup()
51
52 def handleenv(env, startreq, handler):
53     if not "HTTP_HOST" in env:
54         return proto.simpleerror(env, startreq, 400, "Bad Request", "Request must include Host header.")
55     r = req.origrequest(env)
56     return handle(r, startreq, handler)