1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 """
18 Exception handler that's able to extract detailled error informations
19 and write them to a file.
20 """
21
22 __maintainer__ = 'Philippe Normand <philippe@fluendo.com>'
23
24 import cgitb, os, sys
25 import traceback, tempfile
26 from elisa.core import log
27
29 """ Exception handler with detailled error reporting support.
30
31 Extends L{cgitb.Hook}, add a boolean display option indicating
32 wether errors should be displayed on stderr or not. Additionnally,
33 each detailled error report is written to a file on disk on
34 L{logdir} directory.
35
36 Use it like this::
37
38 >>> sys.excepthook = ExceptionHook(format='text', logdir='/tmp',
39 ... file=sys.stderr, display=False)
40
41 """
42
43 - def __init__(self, display=1, logdir=None, context=5, file=None,
44 format="text"):
45
46 if logdir == None:
47 import tempfile
48 logdir = tempfile.gettempdir()
49
50 cgitb.Hook.__init__(self, display, logdir, context, file,
51 format)
52 log.Loggable.__init__(self)
53
54
56 """ add-on to default cgitb.handle():
57
58 - if logdir doesn't exists, create it
59 - if logdir is set, write error report in a text or html file,
60 depending on self.format
61 """
62 import traceback
63
64 if self.logdir is not None and not os.path.exists(self.logdir):
65 try:
66 os.makedirs(self.logdir)
67 except OSError, e:
68
69
70 self.logdir = None
71 self.warning("Could not make directory %r: %r", self.logdir, e)
72 traceback.print_exc()
73
74 info = info or sys.exc_info()
75 if self.format == "html":
76 self.file.write(cgitb.reset())
77
78 formatter = (self.format=="html") and cgitb.html or cgitb.text
79 plain = False
80 try:
81 doc = formatter(info, self.context)
82 except:
83 doc = ''.join(traceback.format_exception(*info))
84 plain = True
85
86 if self.display:
87 self.file.write(doc + '\n')
88 else:
89 self.file.write('A problem occurred in Elisa.\n')
90
91 if self.logdir is not None:
92 suffix = ['.txt', '.html'][self.format=="html"]
93 (fd, path) = tempfile.mkstemp(suffix=suffix, prefix="elisa_",
94 dir=self.logdir)
95 try:
96 file = os.fdopen(fd, 'w')
97 file.write(doc)
98 file.close()
99 msg = '%s contains the description of this error.' % path
100 except:
101 msg = 'Tried to save traceback to %s, but failed.' % path
102 self.file.write(msg + '\n')
103 try:
104 self.file.flush()
105 except:
106 pass
107