我主要为技术精通的人写一个小工具,例如程序员,工程师等等.由于这些工具通常会随着时间的推移而改进,因此我知道将会有未处理的异常,用户不会介意.我希望用户能够向我发送回溯,以便我可以检查发生了什么,并可能改进应用程序.
我通常做wxPython编程,但我最近做了一些Java.我已经把TaskDialog
类挂接到Thread.UncaughtExceptionHandler(),我对结果很满意.特别是它可以捕获和处理任何线程的异常:
我在wxPython中做了类似的工作很长一段时间.然而:
>我不得不写一个装饰器,以便能够从另一个线程打印异常.
>即使在功能上,结果也相当丑陋.
这里是Java和wxPython的代码,所以你可以看到我做了什么:
Java的:
import java.awt.EventQueue; import javax.swing.JFrame; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; import javax.swing.JButton; import java.awt.GridBagLayout; import java.awt.GridBagConstraints; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; import com.ezware.dialog.task.TaskDialogs; public class SwingExceptionTest { private JFrame frame; public static void main(String[] args) { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException e) { } catch (InstantiationException e) { } catch (IllegalAccessException e) { } catch (UnsupportedLookAndFeelException e) { } Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { public void uncaughtException(Thread t,Throwable e) { TaskDialogs.showException(e); } }); EventQueue.invokeLater(new Runnable() { public void run() { try { SwingExceptionTest window = new SwingExceptionTest(); window.frame.setVisible(true); } catch (Exception e) { e.printStackTrace(); } } }); } public SwingExceptionTest() { initialize(); } private void initialize() { frame = new JFrame(); frame.setBounds(100,100,600,400); frame.setDefaultCloSEOperation(JFrame.EXIT_ON_CLOSE); GridBagLayout gridBagLayout = new GridBagLayout(); gridBagLayout.columnWidths = new int[]{0,0}; gridBagLayout.rowHeights = new int[]{0,0}; gridBagLayout.columnWeights = new double[]{0.0,Double.MIN_VALUE}; gridBagLayout.rowWeights = new double[]{0.0,Double.MIN_VALUE}; frame.getContentPane().setLayout(gridBagLayout); JButton btnNewButton = new JButton("Throw!"); btnNewButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { onButton(); } }); GridBagConstraints gbc_btnNewButton = new GridBagConstraints(); gbc_btnNewButton.gridx = 0; gbc_btnNewButton.gridy = 0; frame.getContentPane().add(btnNewButton,gbc_btnNewButton); } protected void onButton(){ Thread worker = new Thread() { public void run() { throw new RuntimeException("Exception!"); } }; worker.start(); } }
wxPython的:
import StringIO import sys import traceback import wx from wx.lib.delayedresult import startWorker def thread_guard(f): def thread_guard_wrapper(*args,**kwargs) : try: r = f(*args,**kwargs) return r except Exception: exc = sys.exc_info() output = StringIO.StringIO() traceback.print_exception(exc[0],exc[1],exc[2],file=output) raise Exception("<THREAD GUARD>\n\n" + output.getvalue()) return thread_guard_wrapper @thread_guard def thread_func(): return 1 / 0 def thread_done(result): r = result.get() print r class MainWindow(wx.Frame): def __init__(self,*args,**kwargs): wx.Frame.__init__(self,**kwargs) self.panel = wx.Panel(self) self.button = wx.Button(self.panel,label="Throw!") self.button.Bind(wx.EVT_BUTTON,self.OnButton) self.sizer = wx.BoxSizer() self.sizer.Add(self.button) self.panel.SetSizerAndFit(self.sizer) self.Show() def OnButton(self,e): startWorker(thread_done,thread_func) app = wx.App(True) win = MainWindow(None,size=(600,400)) app.MainLoop()
现在的问题:
我可以轻松地做一些类似于wxPython中的Java解决方案的东西吗?或者也许,在Java或wxPython中有更好的方法吗?