##// END OF EJS Templates
Update crash handler to give git info, remove obsolete bzr stuff.
Fernando Perez -
Show More
@@ -1,230 +1,228 b''
1 1 # -*- coding: utf-8 -*-
2 2 """sys.excepthook for IPython itself, leaves a detailed report on disk.
3 3
4 4
5 5 Authors
6 6 -------
7 7 - Fernando Perez <Fernando.Perez@berkeley.edu>
8 8 """
9 9
10 10 #*****************************************************************************
11 11 # Copyright (C) 2008-2009 The IPython Development Team
12 12 # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu>
13 13 #
14 14 # Distributed under the terms of the BSD License. The full license is in
15 15 # the file COPYING, distributed as part of this software.
16 16 #*****************************************************************************
17 17
18 18 #****************************************************************************
19 19 # Required modules
20 20
21 21 # From the standard library
22 22 import os
23 23 import sys
24 24 from pprint import pprint,pformat
25 25
26 26 # Our own
27 27 from IPython import Release
28 28 from IPython import ultraTB
29 29 from IPython.ColorANSI import ColorScheme,ColorSchemeTable # too long names
30 30 from IPython.Itpl import Itpl,itpl,printpl
31 31
32 32 from IPython.genutils import *
33 33
34 34 #****************************************************************************
35 35 class CrashHandler:
36 36 """Customizable crash handlers for IPython-based systems.
37 37
38 38 Instances of this class provide a __call__ method which can be used as a
39 39 sys.excepthook, i.e., the __call__ signature is:
40 40
41 41 def __call__(self,etype, evalue, etb)
42 42
43 43 """
44 44
45 45 def __init__(self,IP,app_name,contact_name,contact_email,
46 46 bug_tracker,crash_report_fname,
47 47 show_crash_traceback=True):
48 48 """New crash handler.
49 49
50 50 Inputs:
51 51
52 52 - IP: a running IPython instance, which will be queried at crash time
53 53 for internal information.
54 54
55 55 - app_name: a string containing the name of your application.
56 56
57 57 - contact_name: a string with the name of the person to contact.
58 58
59 59 - contact_email: a string with the email address of the contact.
60 60
61 61 - bug_tracker: a string with the URL for your project's bug tracker.
62 62
63 63 - crash_report_fname: a string with the filename for the crash report
64 64 to be saved in. These reports are left in the ipython user directory
65 65 as determined by the running IPython instance.
66 66
67 67 Optional inputs:
68 68
69 69 - show_crash_traceback(True): if false, don't print the crash
70 70 traceback on stderr, only generate the on-disk report
71 71
72 72
73 73 Non-argument instance attributes:
74 74
75 75 These instances contain some non-argument attributes which allow for
76 76 further customization of the crash handler's behavior. Please see the
77 77 source for further details.
78 78 """
79 79
80 80 # apply args into instance
81 81 self.IP = IP # IPython instance
82 82 self.app_name = app_name
83 83 self.contact_name = contact_name
84 84 self.contact_email = contact_email
85 85 self.bug_tracker = bug_tracker
86 86 self.crash_report_fname = crash_report_fname
87 87 self.show_crash_traceback = show_crash_traceback
88 88
89 89 # Hardcoded defaults, which can be overridden either by subclasses or
90 90 # at runtime for the instance.
91 91
92 92 # Template for the user message. Subclasses which completely override
93 93 # this, or user apps, can modify it to suit their tastes. It gets
94 94 # expanded using itpl, so calls of the kind $self.foo are valid.
95 95 self.user_message_template = """
96 96 Oops, $self.app_name crashed. We do our best to make it stable, but...
97 97
98 98 A crash report was automatically generated with the following information:
99 99 - A verbatim copy of the crash traceback.
100 100 - A copy of your input history during this session.
101 101 - Data on your current $self.app_name configuration.
102 102
103 103 It was left in the file named:
104 104 \t'$self.crash_report_fname'
105 105 If you can email this file to the developers, the information in it will help
106 106 them in understanding and correcting the problem.
107 107
108 108 You can mail it to: $self.contact_name at $self.contact_email
109 109 with the subject '$self.app_name Crash Report'.
110 110
111 111 If you want to do it now, the following command will work (under Unix):
112 112 mail -s '$self.app_name Crash Report' $self.contact_email < $self.crash_report_fname
113 113
114 114 To ensure accurate tracking of this issue, please file a report about it at:
115 115 $self.bug_tracker
116 116 """
117 117
118 118 def __call__(self,etype, evalue, etb):
119 119 """Handle an exception, call for compatible with sys.excepthook"""
120 120
121 121 # Report tracebacks shouldn't use color in general (safer for users)
122 122 color_scheme = 'NoColor'
123 123
124 124 # Use this ONLY for developer debugging (keep commented out for release)
125 125 #color_scheme = 'Linux' # dbg
126 126
127 127 try:
128 128 rptdir = self.IP.rc.ipythondir
129 129 except:
130 130 rptdir = os.getcwd()
131 131 if not os.path.isdir(rptdir):
132 132 rptdir = os.getcwd()
133 133 report_name = os.path.join(rptdir,self.crash_report_fname)
134 134 # write the report filename into the instance dict so it can get
135 135 # properly expanded out in the user message template
136 136 self.crash_report_fname = report_name
137 137 TBhandler = ultraTB.VerboseTB(color_scheme=color_scheme,
138 138 long_header=1)
139 139 traceback = TBhandler.text(etype,evalue,etb,context=31)
140 140
141 141 # print traceback to screen
142 142 if self.show_crash_traceback:
143 143 print >> sys.stderr, traceback
144 144
145 145 # and generate a complete report on disk
146 146 try:
147 147 report = open(report_name,'w')
148 148 except:
149 149 print >> sys.stderr, 'Could not create crash report on disk.'
150 150 return
151 151
152 152 # Inform user on stderr of what happened
153 153 msg = itpl('\n'+'*'*70+'\n'+self.user_message_template)
154 154 print >> sys.stderr, msg
155 155
156 156 # Construct report on disk
157 157 report.write(self.make_report(traceback))
158 158 report.close()
159 159 raw_input("Press enter to exit:")
160 160
161 161 def make_report(self,traceback):
162 162 """Return a string containing a crash report."""
163 163
164 164 sec_sep = '\n\n'+'*'*75+'\n\n'
165 165
166 166 report = []
167 167 rpt_add = report.append
168 168
169 169 rpt_add('*'*75+'\n\n'+'IPython post-mortem report\n\n')
170 170 rpt_add('IPython version: %s \n\n' % Release.version)
171 rpt_add('BZR revision : %s \n\n' % Release.revision)
172 171 rpt_add('Platform info : os.name -> %s, sys.platform -> %s' %
173 172 (os.name,sys.platform) )
174 173 rpt_add(sec_sep+'Current user configuration structure:\n\n')
175 174 rpt_add(pformat(self.IP.rc.dict()))
176 175 rpt_add(sec_sep+'Crash traceback:\n\n' + traceback)
177 176 try:
178 177 rpt_add(sec_sep+"History of session input:")
179 178 for line in self.IP.user_ns['_ih']:
180 179 rpt_add(line)
181 180 rpt_add('\n*** Last line of input (may not be in above history):\n')
182 181 rpt_add(self.IP._last_input_line+'\n')
183 182 except:
184 183 pass
185 184
186 185 return ''.join(report)
187 186
188 187 class IPythonCrashHandler(CrashHandler):
189 188 """sys.excepthook for IPython itself, leaves a detailed report on disk."""
190 189
191 190 def __init__(self,IP):
192 191
193 192 # Set here which of the IPython authors should be listed as contact
194 193 AUTHOR_CONTACT = 'Fernando'
195 194
196 195 # Set argument defaults
197 196 app_name = 'IPython'
198 bug_tracker = 'https://bugs.launchpad.net/ipython/+filebug'
197 bug_tracker = 'https://github.com/ipython/ipython/issues'
199 198 contact_name,contact_email = Release.authors[AUTHOR_CONTACT][:2]
200 199 crash_report_fname = 'IPython_crash_report.txt'
201 200 # Call parent constructor
202 201 CrashHandler.__init__(self,IP,app_name,contact_name,contact_email,
203 202 bug_tracker,crash_report_fname)
204 203
205 204 def make_report(self,traceback):
206 205 """Return a string containing a crash report."""
207 206
208 207 sec_sep = '\n\n'+'*'*75+'\n\n'
209 208
210 209 report = []
211 210 rpt_add = report.append
212 211
213 212 rpt_add('*'*75+'\n\n'+'IPython post-mortem report\n\n')
214 213 rpt_add('IPython version: %s \n\n' % Release.version)
215 rpt_add('BZR revision : %s \n\n' % Release.revision)
216 214 rpt_add('Platform info : os.name -> %s, sys.platform -> %s' %
217 215 (os.name,sys.platform) )
218 216 rpt_add(sec_sep+'Current user configuration structure:\n\n')
219 217 rpt_add(pformat(self.IP.rc.dict()))
220 218 rpt_add(sec_sep+'Crash traceback:\n\n' + traceback)
221 219 try:
222 220 rpt_add(sec_sep+"History of session input:")
223 221 for line in self.IP.user_ns['_ih']:
224 222 rpt_add(line)
225 223 rpt_add('\n*** Last line of input (may not be in above history):\n')
226 224 rpt_add(self.IP._last_input_line+'\n')
227 225 except:
228 226 pass
229 227
230 228 return ''.join(report)
General Comments 0
You need to be logged in to leave comments. Login now