Catch all exception handler in wxpython

yorizzz at gmail.com yorizzz at gmail.com
Thu Feb 1 01:35:26 PST 2007


Robin, thank you for your elaborate answer! So I guess I have no other
option than to parse the output to stderr. This is obviously awkward
since I can't know for sure when the entire message has been sent as
multiple single-line writes to sys.stderr.write().

To help those who find this thread at a later stage, I will post my
current proof-of-concept below. Note that this code has *two*
exception handlers: one for all exceptions that occur outside the
MainLoop (using try-except), and one for all that occur inside the
MainLoop (using stderr). Perhaps if the latter handler is changed into
a modal dialog box and then aborts the program, both types of
exceptions can be caught by the 'stderr' handler, but I haven't tried
that yet.

# Proof-of-concept catch-all exception handler
import wx
import traceback, sys

def fault(testCase):
   unknown = unknown    # raise UnboundLocalError
   div_zero = 1 / 0     # raise ZeroDivisionError

class Main(wx.App):
   def OnInit(self):
      mainFrame = wx.Frame(None, -1, 'Test')
      mainFrame.Show(True)
      self.button = wx.Button(mainFrame, -1, 'Crash!')
      self.Bind(wx.EVT_BUTTON, self.OnCrash, self.button)
      # fault(1)
      return True

   def OnCrash(self, evt):
      fault(2)
      return

# This class handles exceptions in the MainLoop
class MyStderr:
   def __init__(self):
      self.msg = ''
      self.dlg = None
      self.textctrl = None

   def write(self, message):
      if self.dlg == None:
         self.dlg = wx.Frame(None, -1, 'Fatal error')
         self.textctrl = wx.TextCtrl(
                     self.dlg, -1, '',
                     style=wx.TE_MULTILINE|wx.TE_READONLY)
         border = wx.BoxSizer(wx.VERTICAL)
         border.Add(self.textctrl, 1, wx.GROW|wx.ALL, 0)
         self.dlg.SetSizer(border)
         self.dlg.SetAutoLayout(True)
         self.dlg.Layout()
         self.dlg.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
         self.dlg.Show(True)

      self.msg += message
      self.textctrl.SetValue(self.msg)

   def OnCloseWindow(self, evt):
      self.msg = ''
      self.dlg.Destroy()
      self.dlg = None

# Entry point
if __name__ == '__main__':
   sys.stderr = MyStderr()
   try:
      app = Main(0)
      app.MainLoop()
      fault(3)

   except Exception, exception:
      # This handles exceptions before and after the MainLoop
      type, value, stack = sys.exc_info()
      formattedBacktrace = ''.join(traceback.
               format_exception(type, value, stack, 5))
      dlg = wx.MessageDialog(
               None, 'An unexpected problem occurred:\n%s' %
               (formattedBacktrace), 'Fatal error',
               wx.CANCEL | wx.ICON_ERROR)
      dlg.ShowModal()
      dlg.Destroy()







More information about the wx-users mailing list