Commit | Line | Data |
---|---|---|
784d41f3 | 1 | import sys, traceback |
3614ca83 | 2 | from . import env |
784d41f3 | 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] | |
6cf09c76 | 26 | self.__next__() |
e8aa9ce2 FT |
27 | |
28 | def __iter__(self): | |
29 | return self | |
30 | ||
6cf09c76 | 31 | def __next__(self): |
e8aa9ce2 FT |
32 | if self._next is None: |
33 | raise StopIteration() | |
34 | ret = self._next[0] | |
35 | try: | |
6cf09c76 | 36 | self._next[:] = [self.bki.__next__()] |
e8aa9ce2 FT |
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 | 45 | def defaulterror(req, excinfo): |
3614ca83 | 46 | from . import resp |
784d41f3 FT |
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 | 64 | break |
c33f2d6c | 65 | except restart as i: |
d7604bee | 66 | handler = i.handle |
3614ca83 | 67 | except Exception as i: |
784d41f3 FT |
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() |