Skip to content
Browse files

Merge pull request #1008 from minrk/excepthook

Use a much more restrained crash handler by default.

Now the excepthook shows a regular traceback, with a brief message about reporting bugs and how to enable to the big crash handler.  Our previous, extremely verbose crash handler can still be activated via `%config Application.verbose_crash=True`, so we can debug real crashes or ask users for extra detail easily.

Small fixes along the way:

* current Application added to configurables list, for use in %config.

* email addresses in full crash reports changed to ipython-dev, so they don't go straight to individual users.

Should close #695, and ameliorate #833 (doesn't fix the bug, but the message is more sensible).
  • Loading branch information...
2 parents 5e71407 + bb6f87b commit 493f6d4b4e58664724769ea947ba687e59a3ec5c @fperez fperez committed Nov 20, 2011
View
21 IPython/core/application.py
@@ -137,6 +137,11 @@ def _config_files_default(self):
profile, then they will be staged into the new directory. Otherwise,
default config files will be automatically generated.
""")
+
+ verbose_crash = Bool(False, config=True,
+ help="""Create a massive crash report when IPython enconters what may be an
+ internal error. The default is to append a short message to the
+ usual traceback""")
# The class to use as the crash handler.
crash_handler_class = Type(crashhandler.CrashHandler)
@@ -154,11 +159,23 @@ def __init__(self, **kwargs):
def init_crash_handler(self):
"""Create a crash handler, typically setting sys.excepthook to it."""
self.crash_handler = self.crash_handler_class(self)
- sys.excepthook = self.crash_handler
+ sys.excepthook = self.excepthook
def unset_crashhandler():
sys.excepthook = sys.__excepthook__
atexit.register(unset_crashhandler)
-
+
+ def excepthook(self, etype, evalue, tb):
+ """this is sys.excepthook after init_crashhandler
+
+ set self.verbose_crash=True to use our full crashhandler, instead of
+ a regular traceback with a short message (crash_handler_lite)
+ """
+
+ if self.verbose_crash:
+ return self.crash_handler(etype, evalue, tb)
+ else:
+ return crashhandler.crash_handler_lite(etype, evalue, tb)
+
def _ipython_dir_changed(self, name, old, new):
if old in sys.path:
sys.path.remove(old)
View
27 IPython/core/crashhandler.py
@@ -21,9 +21,11 @@
import os
import sys
+import traceback
from pprint import pformat
from IPython.core import ultratb
+from IPython.core.release import author_email
from IPython.utils.sysinfo import sys_info
#-----------------------------------------------------------------------------
@@ -54,6 +56,15 @@
{bug_tracker}
"""
+_lite_message_template = """
+If you suspect this is an IPython bug, please report it at:
+ https://github.com/ipython/ipython/issues
+or send an email to the mailing list at {email}
+
+You can enable a much more verbose traceback with:
+ {config}Application.verbose_crash=True
+"""
+
class CrashHandler(object):
"""Customizable crash handlers for IPython applications.
@@ -161,7 +172,7 @@ def __call__(self, etype, evalue, etb):
# Construct report on disk
report.write(self.make_report(traceback))
report.close()
- raw_input("Hit <Enter> to quit this message (your terminal may close):")
+ raw_input("Hit <Enter> to quit (your terminal may close):")
def make_report(self,traceback):
"""Return a string containing a crash report."""
@@ -184,3 +195,17 @@ def make_report(self,traceback):
return ''.join(report)
+
+def crash_handler_lite(etype, evalue, tb):
+ """a light excepthook, adding a small message to the usual traceback"""
+ traceback.print_exception(etype, evalue, tb)
+
+ from IPython.core.interactiveshell import InteractiveShell
+ if InteractiveShell.initialized():
+ # we are in a Shell environment, give %magic example
+ config = "%config "
+ else:
+ # we are not in a shell, show generic config
+ config = "c."
+ print >> sys.stderr, _lite_message_template.format(email=author_email, config=config)
+
View
5 IPython/frontend/terminal/ipapp.py
@@ -81,8 +81,8 @@ class IPAppCrashHandler(CrashHandler):
def __init__(self, app):
contact_name = release.authors['Fernando'][0]
- contact_email = release.authors['Fernando'][1]
- bug_tracker = 'http://github.com/ipython/ipython/issues'
+ contact_email = release.author_email
+ bug_tracker = 'https://github.com/ipython/ipython/issues'
super(IPAppCrashHandler,self).__init__(
app, contact_name, contact_email, bug_tracker
)
@@ -320,6 +320,7 @@ def init_shell(self):
self.shell = TerminalInteractiveShell.instance(config=self.config,
display_banner=False, profile_dir=self.profile_dir,
ipython_dir=self.ipython_dir)
+ self.shell.configurables.append(self)
def init_banner(self):
"""optionally display the banner"""
View
4 IPython/parallel/apps/baseapp.py
@@ -58,8 +58,8 @@ class ParallelCrashHandler(CrashHandler):
def __init__(self, app):
contact_name = release.authors['Min'][0]
- contact_email = release.authors['Min'][1]
- bug_tracker = 'http://github.com/ipython/ipython/issues'
+ contact_email = release.author_email
+ bug_tracker = 'https://github.com/ipython/ipython/issues'
super(ParallelCrashHandler,self).__init__(
app, contact_name, contact_email, bug_tracker
)
View
1 IPython/zmq/ipkernel.py
@@ -780,6 +780,7 @@ def print_tb(etype, evalue, stb):
def init_shell(self):
self.shell = self.kernel.shell
+ self.shell.configurables.append(self)
#-----------------------------------------------------------------------------

0 comments on commit 493f6d4

Please sign in to comment.
Something went wrong with that request. Please try again.