Skip to content

Commit 197f56e

Browse files
committed
Catch errors while trying to display an error and provide a nice ARGH! dialog.
1 parent c5e03c1 commit 197f56e

File tree

1 file changed

+49
-5
lines changed

1 file changed

+49
-5
lines changed

bpython/gtk_.py

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,45 @@ def formatvalue(self, value):
6969
return '=%s' % (value, )
7070

7171

72+
class ExceptionDialog(gtk.MessageDialog):
73+
def __init__(self, exc_type, exc_value, tb, text='An error occurred.'):
74+
gtk.MessageDialog.__init__(self, buttons=gtk.BUTTONS_CLOSE,
75+
type=gtk.MESSAGE_ERROR,
76+
message_format=text)
77+
self.set_resizable(True)
78+
import cgitb
79+
text = cgitb.text((exc_type, exc_value, tb), 5)
80+
expander = gtk.Expander('Exception details')
81+
self.vbox.pack_start(expander)
82+
textview = gtk.TextView()
83+
textview.get_buffer().set_text(text)
84+
scrolled_window = gtk.ScrolledWindow()
85+
scrolled_window.add(textview)
86+
expander.add(scrolled_window)
87+
self.show_all()
88+
89+
90+
class ExceptionManager(object):
91+
"""
92+
A context manager which runs the dialog `DialogType` on error, with
93+
the exception's type, value, a traceback and a text to display as
94+
arguments.
95+
"""
96+
def __init__(self, DialogType, text='An error occurred.'):
97+
self.DialogType = DialogType
98+
self.text = text
99+
100+
def __enter__(self):
101+
return self
102+
103+
def __exit__(self, exc_type, exc_value, traceback):
104+
if not (exc_value is None or
105+
issubclass(exc_type, (KeyboardInterrupt, SystemExit))):
106+
dialog = self.DialogType(exc_type, exc_value, traceback, self.text)
107+
dialog.run()
108+
dialog.destroy()
109+
110+
72111
class Nested(object):
73112
"""
74113
A helper class, inspired by a semaphore.
@@ -555,11 +594,16 @@ def set_cursor_to_valid_insert_position(self):
555594
self.text_buffer.place_cursor(line_start_iter)
556595

557596
def writetb(self, lines):
558-
string = ''.join(lines)
559-
with self.editing:
560-
self.text_buffer.insert_with_tags_by_name(self.get_cursor_iter(),
561-
string, 'error')
562-
self.move_cursor(len(string))
597+
with ExceptionManager(ExceptionDialog,
598+
'An error occured while trying to display '
599+
'an error. Please contact the bpython '
600+
'developers.'):
601+
string = ''.join(lines)
602+
with self.editing:
603+
self.text_buffer.insert_with_tags_by_name(
604+
self.get_cursor_iter(), string, 'error'
605+
)
606+
self.move_cursor(len(string))
563607

564608

565609
def init_import_completion():

0 commit comments

Comments
 (0)