Show More
@@ -119,14 +119,13 b' class Application(object):' | |||||
119 | argv = None |
|
119 | argv = None | |
120 | #: extra arguments computed by the command-line loader |
|
120 | #: extra arguments computed by the command-line loader | |
121 | extra_args = None |
|
121 | extra_args = None | |
|
122 | #: The class to use as the crash handler. | |||
|
123 | crash_handler_class = crashhandler.CrashHandler | |||
122 |
|
124 | |||
123 | # Private attributes |
|
125 | # Private attributes | |
124 | _exiting = False |
|
126 | _exiting = False | |
125 | _initialized = False |
|
127 | _initialized = False | |
126 |
|
128 | |||
127 | # Class choices for things that will be instantiated at runtime. |
|
|||
128 | _CrashHandler = crashhandler.CrashHandler |
|
|||
129 |
|
||||
130 | def __init__(self, argv=None): |
|
129 | def __init__(self, argv=None): | |
131 | self.argv = sys.argv[1:] if argv is None else argv |
|
130 | self.argv = sys.argv[1:] if argv is None else argv | |
132 | self.init_logger() |
|
131 | self.init_logger() | |
@@ -217,7 +216,7 b' class Application(object):' | |||||
217 |
|
216 | |||
218 | def create_crash_handler(self): |
|
217 | def create_crash_handler(self): | |
219 | """Create a crash handler, typically setting sys.excepthook to it.""" |
|
218 | """Create a crash handler, typically setting sys.excepthook to it.""" | |
220 |
self.crash_handler = self. |
|
219 | self.crash_handler = self.crash_handler_class(self) | |
221 | sys.excepthook = self.crash_handler |
|
220 | sys.excepthook = self.crash_handler | |
222 |
|
221 | |||
223 | def create_default_config(self): |
|
222 | def create_default_config(self): | |
@@ -430,15 +429,6 b' class Application(object):' | |||||
430 | # Utility methods |
|
429 | # Utility methods | |
431 | #------------------------------------------------------------------------- |
|
430 | #------------------------------------------------------------------------- | |
432 |
|
431 | |||
433 | def abort(self): |
|
|||
434 | """Abort the starting of the application.""" |
|
|||
435 | if self._exiting: |
|
|||
436 | pass |
|
|||
437 | else: |
|
|||
438 | self.log.critical("Aborting application: %s" % self.name, exc_info=True) |
|
|||
439 | self._exiting = True |
|
|||
440 | sys.exit(1) |
|
|||
441 |
|
||||
442 | def exit(self, exit_status=0): |
|
432 | def exit(self, exit_status=0): | |
443 | if self._exiting: |
|
433 | if self._exiting: | |
444 | pass |
|
434 | pass | |
@@ -447,17 +437,13 b' class Application(object):' | |||||
447 | self._exiting = True |
|
437 | self._exiting = True | |
448 | sys.exit(exit_status) |
|
438 | sys.exit(exit_status) | |
449 |
|
439 | |||
450 |
def attempt(self, func |
|
440 | def attempt(self, func): | |
451 | try: |
|
441 | try: | |
452 | func() |
|
442 | func() | |
453 | except SystemExit: |
|
443 | except SystemExit: | |
454 | raise |
|
444 | raise | |
455 | except: |
|
445 | except: | |
456 | if action == 'abort': |
|
|||
457 |
|
|
446 | self.log.critical("Aborting application: %s" % self.name, | |
458 |
|
|
447 | exc_info=True) | |
459 | self.abort() |
|
|||
460 | raise |
|
|||
461 | elif action == 'exit': |
|
|||
462 |
|
|
448 | self.exit(0) | |
463 |
|
449 |
@@ -1,74 +1,94 b'' | |||||
1 |
# |
|
1 | # encoding: utf-8 | |
2 | """sys.excepthook for IPython itself, leaves a detailed report on disk. |
|
2 | """sys.excepthook for IPython itself, leaves a detailed report on disk. | |
3 |
|
3 | |||
|
4 | Authors: | |||
4 |
|
5 | |||
5 | Authors |
|
6 | * Fernando Perez | |
6 | ------- |
|
7 | * Brian E. Granger | |
7 | - Fernando Perez <Fernando.Perez@berkeley.edu> |
|
|||
8 | """ |
|
8 | """ | |
9 |
|
9 | |||
10 | #***************************************************************************** |
|
10 | #----------------------------------------------------------------------------- | |
11 | # Copyright (C) 2008-2009 The IPython Development Team |
|
|||
12 |
# |
|
11 | # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu> | |
|
12 | # Copyright (C) 2008-2010 The IPython Development Team | |||
13 | # |
|
13 | # | |
14 | # Distributed under the terms of the BSD License. The full license is in |
|
14 | # Distributed under the terms of the BSD License. The full license is in | |
15 | # the file COPYING, distributed as part of this software. |
|
15 | # the file COPYING, distributed as part of this software. | |
16 | #***************************************************************************** |
|
16 | #----------------------------------------------------------------------------- | |
17 |
|
17 | |||
18 | #**************************************************************************** |
|
18 | #----------------------------------------------------------------------------- | |
19 | # Required modules |
|
19 | # Imports | |
|
20 | #----------------------------------------------------------------------------- | |||
20 |
|
21 | |||
21 | # From the standard library |
|
|||
22 | import os |
|
22 | import os | |
23 | import sys |
|
23 | import sys | |
24 | from pprint import pformat |
|
24 | from pprint import pformat | |
25 |
|
25 | |||
26 | # Our own |
|
|||
27 | from IPython.core import release |
|
|||
28 | from IPython.core import ultratb |
|
26 | from IPython.core import ultratb | |
|
27 | from IPython.external.Itpl import itpl | |||
29 | from IPython.utils.sysinfo import sys_info |
|
28 | from IPython.utils.sysinfo import sys_info | |
30 |
|
29 | |||
31 | from IPython.external.Itpl import itpl |
|
30 | #----------------------------------------------------------------------------- | |
|
31 | # Code | |||
|
32 | #----------------------------------------------------------------------------- | |||
32 |
|
33 | |||
33 | #**************************************************************************** |
|
34 | # Template for the user message. | |
|
35 | _default_message_template = """\ | |||
|
36 | Oops, $self.app_name crashed. We do our best to make it stable, but... | |||
34 |
|
37 | |||
35 | class CrashHandler(object): |
|
38 | A crash report was automatically generated with the following information: | |
36 | """Customizable crash handlers for IPython-based systems. |
|
39 | - A verbatim copy of the crash traceback. | |
|
40 | - A copy of your input history during this session. | |||
|
41 | - Data on your current $self.app_name configuration. | |||
37 |
|
42 | |||
38 | Instances of this class provide a __call__ method which can be used as a |
|
43 | It was left in the file named: | |
39 | sys.excepthook, i.e., the __call__ signature is: |
|
44 | \t'$self.crash_report_fname' | |
|
45 | If you can email this file to the developers, the information in it will help | |||
|
46 | them in understanding and correcting the problem. | |||
40 |
|
47 | |||
41 | def __call__(self,etype, evalue, etb) |
|
48 | You can mail it to: $self.contact_name at $self.contact_email | |
|
49 | with the subject '$self.app_name Crash Report'. | |||
|
50 | ||||
|
51 | If you want to do it now, the following command will work (under Unix): | |||
|
52 | mail -s '$self.app_name Crash Report' $self.contact_email < $self.crash_report_fname | |||
42 |
|
53 | |||
|
54 | To ensure accurate tracking of this issue, please file a report about it at: | |||
|
55 | $self.bug_tracker | |||
43 |
|
|
56 | """ | |
44 |
|
57 | |||
45 | def __init__(self,app, app_name, contact_name=None, contact_email=None, |
|
|||
46 | bug_tracker=None, crash_report_fname='CrashReport.txt', |
|
|||
47 | show_crash_traceback=True, call_pdb=False): |
|
|||
48 | """New crash handler. |
|
|||
49 |
|
58 | |||
50 | Inputs: |
|
59 | class CrashHandler(object): | |
|
60 | """Customizable crash handlers for IPython applications. | |||
51 |
|
61 | |||
52 | - app: a running application instance, which will be queried at crash |
|
62 | Instances of this class provide a :meth:`__call__` method which can be | |
53 | time for internal information. |
|
63 | used as a ``sys.excepthook``. The :meth:`__call__` signature is:: | |
54 |
|
64 | |||
55 | - app_name: a string containing the name of your application. |
|
65 | def __call__(self, etype, evalue, etb) | |
|
66 | """ | |||
56 |
|
67 | |||
57 | - contact_name: a string with the name of the person to contact. |
|
68 | message_template = _default_message_template | |
58 |
|
69 | |||
59 | - contact_email: a string with the email address of the contact. |
|
70 | def __init__(self, app, contact_name=None, contact_email=None, | |
|
71 | bug_tracker=None, show_crash_traceback=True, call_pdb=False): | |||
|
72 | """Create a new crash handler | |||
60 |
|
73 | |||
61 | - bug_tracker: a string with the URL for your project's bug tracker. |
|
74 | Parameters | |
|
75 | ---------- | |||
|
76 | app : Application | |||
|
77 | A running :class:`Application` instance, which will be queried at | |||
|
78 | crash time for internal information. | |||
62 |
|
79 | |||
63 | - crash_report_fname: a string with the filename for the crash report |
|
80 | contact_name : str | |
64 | to be saved in. These reports are left in the ipython user directory |
|
81 | A string with the name of the person to contact. | |
65 | as determined by the running IPython instance. |
|
|||
66 |
|
82 | |||
67 | Optional inputs: |
|
83 | contact_email : str | |
|
84 | A string with the email address of the contact. | |||
68 |
|
85 | |||
69 | - show_crash_traceback(True): if false, don't print the crash |
|
86 | bug_tracker : str | |
70 | traceback on stderr, only generate the on-disk report |
|
87 | A string with the URL for your project's bug tracker. | |
71 |
|
88 | |||
|
89 | show_crash_traceback : bool | |||
|
90 | If false, don't print the crash traceback on stderr, only generate | |||
|
91 | the on-disk report | |||
72 |
|
92 | |||
73 | Non-argument instance attributes: |
|
93 | Non-argument instance attributes: | |
74 |
|
94 | |||
@@ -76,48 +96,17 b' class CrashHandler(object):' | |||||
76 |
further customization of the crash handler's behavior. |
|
96 | further customization of the crash handler's behavior. Please see the | |
77 | source for further details. |
|
97 | source for further details. | |
78 | """ |
|
98 | """ | |
79 |
|
||||
80 | # apply args into instance |
|
|||
81 | self.app = app |
|
99 | self.app = app | |
82 |
self.app_name = |
|
100 | self.app_name = self.app.name | |
83 | self.contact_name = contact_name |
|
101 | self.contact_name = contact_name | |
84 | self.contact_email = contact_email |
|
102 | self.contact_email = contact_email | |
85 | self.bug_tracker = bug_tracker |
|
103 | self.bug_tracker = bug_tracker | |
86 |
self.crash_report_fname = |
|
104 | self.crash_report_fname = "Crash_report_%s.txt" % self.app_name | |
87 | self.show_crash_traceback = show_crash_traceback |
|
105 | self.show_crash_traceback = show_crash_traceback | |
88 | self.section_sep = '\n\n'+'*'*75+'\n\n' |
|
106 | self.section_sep = '\n\n'+'*'*75+'\n\n' | |
89 | self.call_pdb = call_pdb |
|
107 | self.call_pdb = call_pdb | |
90 | #self.call_pdb = True # dbg |
|
108 | #self.call_pdb = True # dbg | |
91 |
|
109 | |||
92 | # Hardcoded defaults, which can be overridden either by subclasses or |
|
|||
93 | # at runtime for the instance. |
|
|||
94 |
|
||||
95 | # Template for the user message. Subclasses which completely override |
|
|||
96 | # this, or user apps, can modify it to suit their tastes. It gets |
|
|||
97 | # expanded using itpl, so calls of the kind $self.foo are valid. |
|
|||
98 | self.user_message_template = """ |
|
|||
99 | Oops, $self.app_name crashed. We do our best to make it stable, but... |
|
|||
100 |
|
||||
101 | A crash report was automatically generated with the following information: |
|
|||
102 | - A verbatim copy of the crash traceback. |
|
|||
103 | - A copy of your input history during this session. |
|
|||
104 | - Data on your current $self.app_name configuration. |
|
|||
105 |
|
||||
106 | It was left in the file named: |
|
|||
107 | \t'$self.crash_report_fname' |
|
|||
108 | If you can email this file to the developers, the information in it will help |
|
|||
109 | them in understanding and correcting the problem. |
|
|||
110 |
|
||||
111 | You can mail it to: $self.contact_name at $self.contact_email |
|
|||
112 | with the subject '$self.app_name Crash Report'. |
|
|||
113 |
|
||||
114 | If you want to do it now, the following command will work (under Unix): |
|
|||
115 | mail -s '$self.app_name Crash Report' $self.contact_email < $self.crash_report_fname |
|
|||
116 |
|
||||
117 | To ensure accurate tracking of this issue, please file a report about it at: |
|
|||
118 | $self.bug_tracker |
|
|||
119 | """ |
|
|||
120 |
|
||||
121 | def __call__(self,etype, evalue, etb): |
|
110 | def __call__(self, etype, evalue, etb): | |
122 | """Handle an exception, call for compatible with sys.excepthook""" |
|
111 | """Handle an exception, call for compatible with sys.excepthook""" | |
123 |
|
112 | |||
@@ -137,7 +126,8 b' $self.bug_tracker' | |||||
137 | # write the report filename into the instance dict so it can get |
|
126 | # write the report filename into the instance dict so it can get | |
138 | # properly expanded out in the user message template |
|
127 | # properly expanded out in the user message template | |
139 | self.crash_report_fname = report_name |
|
128 | self.crash_report_fname = report_name | |
140 |
TBhandler = ultratb.VerboseTB( |
|
129 | TBhandler = ultratb.VerboseTB( | |
|
130 | color_scheme=color_scheme, | |||
141 |
|
|
131 | long_header=1, | |
142 |
|
|
132 | call_pdb=self.call_pdb, | |
143 | ) |
|
133 | ) | |
@@ -159,7 +149,7 b' $self.bug_tracker' | |||||
159 | return |
|
149 | return | |
160 |
|
150 | |||
161 | # Inform user on stderr of what happened |
|
151 | # Inform user on stderr of what happened | |
162 |
msg = itpl('\n'+'*'*70+'\n'+self. |
|
152 | msg = itpl('\n'+'*'*70+'\n'+self.message_template) | |
163 | print >> sys.stderr, msg |
|
153 | print >> sys.stderr, msg | |
164 |
|
154 | |||
165 | # Construct report on disk |
|
155 | # Construct report on disk | |
@@ -178,7 +168,9 b' $self.bug_tracker' | |||||
178 |
|
168 | |||
179 | try: |
|
169 | try: | |
180 | config = pformat(self.app.config) |
|
170 | config = pformat(self.app.config) | |
181 | rpt_add(sec_sep+'Current user configuration structure:\n\n') |
|
171 | rpt_add(sec_sep) | |
|
172 | rpt_add('Application name: %s\n\n' % self.app_name) | |||
|
173 | rpt_add('Current user configuration structure:\n\n') | |||
182 | rpt_add(config) |
|
174 | rpt_add(config) | |
183 | except: |
|
175 | except: | |
184 | pass |
|
176 | pass | |
@@ -186,39 +178,3 b' $self.bug_tracker' | |||||
186 |
|
178 | |||
187 | return ''.join(report) |
|
179 | return ''.join(report) | |
188 |
|
180 | |||
189 |
|
||||
190 | class IPythonCrashHandler(CrashHandler): |
|
|||
191 | """sys.excepthook for IPython itself, leaves a detailed report on disk.""" |
|
|||
192 |
|
||||
193 | def __init__(self, app, app_name='IPython'): |
|
|||
194 |
|
||||
195 | # Set here which of the IPython authors should be listed as contact |
|
|||
196 | AUTHOR_CONTACT = 'Fernando' |
|
|||
197 |
|
||||
198 | # Set argument defaults |
|
|||
199 | bug_tracker = 'https://bugs.launchpad.net/ipython/+filebug' |
|
|||
200 | contact_name,contact_email = release.authors[AUTHOR_CONTACT][:2] |
|
|||
201 | crash_report_fname = 'IPython_crash_report.txt' |
|
|||
202 | # Call parent constructor |
|
|||
203 | CrashHandler.__init__(self,app,app_name,contact_name,contact_email, |
|
|||
204 | bug_tracker,crash_report_fname) |
|
|||
205 |
|
||||
206 | def make_report(self,traceback): |
|
|||
207 | """Return a string containing a crash report.""" |
|
|||
208 |
|
||||
209 | sec_sep = self.section_sep |
|
|||
210 | # Start with parent report |
|
|||
211 | report = [super(IPythonCrashHandler, self).make_report(traceback)] |
|
|||
212 | # Add interactive-specific info we may have |
|
|||
213 | rpt_add = report.append |
|
|||
214 | try: |
|
|||
215 | rpt_add(sec_sep+"History of session input:") |
|
|||
216 | for line in self.app.shell.user_ns['_ih']: |
|
|||
217 | rpt_add(line) |
|
|||
218 | rpt_add('\n*** Last line of input (may not be in above history):\n') |
|
|||
219 | rpt_add(self.app.shell._last_input_line+'\n') |
|
|||
220 | except: |
|
|||
221 | pass |
|
|||
222 |
|
||||
223 | return ''.join(report) |
|
|||
224 |
|
@@ -21,13 +21,15 b' Authors' | |||||
21 | #----------------------------------------------------------------------------- |
|
21 | #----------------------------------------------------------------------------- | |
22 | # Imports |
|
22 | # Imports | |
23 | #----------------------------------------------------------------------------- |
|
23 | #----------------------------------------------------------------------------- | |
|
24 | ||||
24 | from __future__ import absolute_import |
|
25 | from __future__ import absolute_import | |
25 |
|
26 | |||
26 | import logging |
|
27 | import logging | |
27 | import os |
|
28 | import os | |
28 | import sys |
|
29 | import sys | |
29 |
|
30 | |||
30 |
from IPython.core import |
|
31 | from IPython.core import release | |
|
32 | from IPython.core.crashhandler import CrashHandler | |||
31 | from IPython.core.application import Application, BaseAppConfigLoader |
|
33 | from IPython.core.application import Application, BaseAppConfigLoader | |
32 | from IPython.core.iplib import InteractiveShell |
|
34 | from IPython.core.iplib import InteractiveShell | |
33 | from IPython.config.loader import ( |
|
35 | from IPython.config.loader import ( | |
@@ -317,6 +319,67 b' class IPAppConfigLoader(BaseAppConfigLoader):' | |||||
317 |
|
319 | |||
318 |
|
320 | |||
319 | #----------------------------------------------------------------------------- |
|
321 | #----------------------------------------------------------------------------- | |
|
322 | # Crash handler for this application | |||
|
323 | #----------------------------------------------------------------------------- | |||
|
324 | ||||
|
325 | ||||
|
326 | _message_template = """\ | |||
|
327 | Oops, $self.app_name crashed. We do our best to make it stable, but... | |||
|
328 | ||||
|
329 | A crash report was automatically generated with the following information: | |||
|
330 | - A verbatim copy of the crash traceback. | |||
|
331 | - A copy of your input history during this session. | |||
|
332 | - Data on your current $self.app_name configuration. | |||
|
333 | ||||
|
334 | It was left in the file named: | |||
|
335 | \t'$self.crash_report_fname' | |||
|
336 | If you can email this file to the developers, the information in it will help | |||
|
337 | them in understanding and correcting the problem. | |||
|
338 | ||||
|
339 | You can mail it to: $self.contact_name at $self.contact_email | |||
|
340 | with the subject '$self.app_name Crash Report'. | |||
|
341 | ||||
|
342 | If you want to do it now, the following command will work (under Unix): | |||
|
343 | mail -s '$self.app_name Crash Report' $self.contact_email < $self.crash_report_fname | |||
|
344 | ||||
|
345 | To ensure accurate tracking of this issue, please file a report about it at: | |||
|
346 | $self.bug_tracker | |||
|
347 | """ | |||
|
348 | ||||
|
349 | class IPAppCrashHandler(CrashHandler): | |||
|
350 | """sys.excepthook for IPython itself, leaves a detailed report on disk.""" | |||
|
351 | ||||
|
352 | message_template = _message_template | |||
|
353 | ||||
|
354 | def __init__(self, app): | |||
|
355 | contact_name = release.authors['Fernando'][0] | |||
|
356 | contact_email = release.authors['Fernando'][1] | |||
|
357 | bug_tracker = 'https://bugs.launchpad.net/ipython/+filebug' | |||
|
358 | super(IPAppCrashHandler,self).__init__( | |||
|
359 | app, contact_name, contact_email, bug_tracker | |||
|
360 | ) | |||
|
361 | ||||
|
362 | def make_report(self,traceback): | |||
|
363 | """Return a string containing a crash report.""" | |||
|
364 | ||||
|
365 | sec_sep = self.section_sep | |||
|
366 | # Start with parent report | |||
|
367 | report = [super(IPAppCrashHandler, self).make_report(traceback)] | |||
|
368 | # Add interactive-specific info we may have | |||
|
369 | rpt_add = report.append | |||
|
370 | try: | |||
|
371 | rpt_add(sec_sep+"History of session input:") | |||
|
372 | for line in self.app.shell.user_ns['_ih']: | |||
|
373 | rpt_add(line) | |||
|
374 | rpt_add('\n*** Last line of input (may not be in above history):\n') | |||
|
375 | rpt_add(self.app.shell._last_input_line+'\n') | |||
|
376 | except: | |||
|
377 | pass | |||
|
378 | ||||
|
379 | return ''.join(report) | |||
|
380 | ||||
|
381 | ||||
|
382 | #----------------------------------------------------------------------------- | |||
320 | # Main classes and functions |
|
383 | # Main classes and functions | |
321 | #----------------------------------------------------------------------------- |
|
384 | #----------------------------------------------------------------------------- | |
322 |
|
385 | |||
@@ -327,9 +390,7 b' class IPythonApp(Application):' | |||||
327 | usage = usage.cl_usage |
|
390 | usage = usage.cl_usage | |
328 | command_line_loader = IPAppConfigLoader |
|
391 | command_line_loader = IPAppConfigLoader | |
329 | config_file_name = default_config_file_name |
|
392 | config_file_name = default_config_file_name | |
330 |
|
393 | crash_handler_class = IPAppCrashHandler | ||
331 | # Private and configuration attributes |
|
|||
332 | _CrashHandler = crashhandler.IPythonCrashHandler |
|
|||
333 |
|
394 | |||
334 | def create_default_config(self): |
|
395 | def create_default_config(self): | |
335 | super(IPythonApp, self).create_default_config() |
|
396 | super(IPythonApp, self).create_default_config() |
@@ -27,6 +27,8 b' from twisted.python import log' | |||||
27 | from IPython.config.loader import PyFileConfigLoader |
|
27 | from IPython.config.loader import PyFileConfigLoader | |
28 | from IPython.core.application import Application, BaseAppConfigLoader |
|
28 | from IPython.core.application import Application, BaseAppConfigLoader | |
29 | from IPython.core.component import Component |
|
29 | from IPython.core.component import Component | |
|
30 | from IPython.core.crashhandler import CrashHandler | |||
|
31 | from IPython.core import release | |||
30 | from IPython.utils.path import ( |
|
32 | from IPython.utils.path import ( | |
31 | get_ipython_package_dir, |
|
33 | get_ipython_package_dir, | |
32 | expand_path |
|
34 | expand_path | |
@@ -290,6 +292,47 b' class ClusterDirConfigLoader(BaseAppConfigLoader):' | |||||
290 |
|
292 | |||
291 |
|
293 | |||
292 | #----------------------------------------------------------------------------- |
|
294 | #----------------------------------------------------------------------------- | |
|
295 | # Crash handler for this application | |||
|
296 | #----------------------------------------------------------------------------- | |||
|
297 | ||||
|
298 | ||||
|
299 | _message_template = """\ | |||
|
300 | Oops, $self.app_name crashed. We do our best to make it stable, but... | |||
|
301 | ||||
|
302 | A crash report was automatically generated with the following information: | |||
|
303 | - A verbatim copy of the crash traceback. | |||
|
304 | - Data on your current $self.app_name configuration. | |||
|
305 | ||||
|
306 | It was left in the file named: | |||
|
307 | \t'$self.crash_report_fname' | |||
|
308 | If you can email this file to the developers, the information in it will help | |||
|
309 | them in understanding and correcting the problem. | |||
|
310 | ||||
|
311 | You can mail it to: $self.contact_name at $self.contact_email | |||
|
312 | with the subject '$self.app_name Crash Report'. | |||
|
313 | ||||
|
314 | If you want to do it now, the following command will work (under Unix): | |||
|
315 | mail -s '$self.app_name Crash Report' $self.contact_email < $self.crash_report_fname | |||
|
316 | ||||
|
317 | To ensure accurate tracking of this issue, please file a report about it at: | |||
|
318 | $self.bug_tracker | |||
|
319 | """ | |||
|
320 | ||||
|
321 | class ClusterDirCrashHandler(CrashHandler): | |||
|
322 | """sys.excepthook for IPython itself, leaves a detailed report on disk.""" | |||
|
323 | ||||
|
324 | message_template = _message_template | |||
|
325 | ||||
|
326 | def __init__(self, app): | |||
|
327 | contact_name = release.authors['Brian'][0] | |||
|
328 | contact_email = release.authors['Brian'][1] | |||
|
329 | bug_tracker = 'https://bugs.launchpad.net/ipython/+filebug' | |||
|
330 | super(ClusterDirCrashHandler,self).__init__( | |||
|
331 | app, contact_name, contact_email, bug_tracker | |||
|
332 | ) | |||
|
333 | ||||
|
334 | ||||
|
335 | #----------------------------------------------------------------------------- | |||
293 | # Main application |
|
336 | # Main application | |
294 | #----------------------------------------------------------------------------- |
|
337 | #----------------------------------------------------------------------------- | |
295 |
|
338 | |||
@@ -313,6 +356,7 b' class ApplicationWithClusterDir(Application):' | |||||
313 | """ |
|
356 | """ | |
314 |
|
357 | |||
315 | command_line_loader = ClusterDirConfigLoader |
|
358 | command_line_loader = ClusterDirConfigLoader | |
|
359 | crash_handler_class = ClusterDirCrashHandler | |||
316 | auto_create_cluster_dir = True |
|
360 | auto_create_cluster_dir = True | |
317 |
|
361 | |||
318 | def create_default_config(self): |
|
362 | def create_default_config(self): |
General Comments 0
You need to be logged in to leave comments.
Login now