Commit | Line | Data |
---|---|---|
784d41f3 FT |
1 | import sys, traceback |
2 | import env | |
3 | ||
b409a338 FT |
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 | ||
e8aa9ce2 FT |
19 | class iterproxy(object): |
20 | # Makes sure iter(real).next() is called immediately, in order to | |
21 | # let generator code run. | |
22 | def __init__(self, real): | |
23 | self.bk = real | |
24 | self.bki = iter(real) | |
25 | self._next = [None] | |
26 | self.next() | |
27 | ||
28 | def __iter__(self): | |
29 | return self | |
30 | ||
31 | def next(self): | |
32 | if self._next is None: | |
33 | raise StopIteration() | |
34 | ret = self._next[0] | |
35 | try: | |
36 | self._next[:] = [self.bki.next()] | |
37 | except StopIteration: | |
38 | self._next = None | |
39 | return ret | |
40 | ||
41 | def close(self): | |
42 | if hasattr(self.bk, "close"): | |
43 | self.bk.close() | |
44 | ||
784d41f3 FT |
45 | def defaulterror(req, excinfo): |
46 | import resp | |
47 | traceback.print_exception(*excinfo) | |
48 | raise resp.httperror(500) | |
49 | ||
50 | def wraphandler(handler, excinfo): | |
51 | def wrapped(req): | |
52 | return handler(req, excinfo) | |
53 | return wrapped | |
54 | ||
55 | errorhandler = env.var(defaulterror) | |
56 | ||
b409a338 | 57 | def handle(req, startreq, handler): |
784d41f3 | 58 | eh = errorhandler.val |
b409a338 FT |
59 | try: |
60 | resp = [""] | |
61 | while True: | |
62 | try: | |
e8aa9ce2 | 63 | resp = iterproxy(handler(req)) |
b409a338 FT |
64 | break |
65 | except restart, i: | |
d7604bee | 66 | handler = i.handle |
784d41f3 FT |
67 | except Exception, i: |
68 | if eh is None: | |
69 | raise | |
70 | handler = wraphandler(eh, sys.exc_info()) | |
71 | eh = None | |
b409a338 FT |
72 | req.commit(startreq) |
73 | return resp | |
74 | finally: | |
75 | req.cleanup() |