2014-08-31 41 views
3

我想弄清楚如何去倾听Java中的错误。我想要做的是在控制台发生错误时,程序会检测并简化它(堆栈跟踪可能会很吓人!)。如何监听日志中的错误?

这里是我的尝试:

 Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() 
     { 
      @Override 
      public void uncaughtException(Thread t, Throwable e) 
      { 
       // do some good stuff here, like logging or sending an alert email to the Support team 
       System.out.println("EXCEPTION CAUGHT!"); 
       System.out.println(e.getMessage()); 
      } 
     }); 

但不幸的是,它不是说捕获异常!发生错误时。我应该这样做吗,还是有一些方法可以在更新时监听System.out日志?

+0

这只是一种处理线程未捕获异常的方法。你可以做任何你可以在这里想象。没有正确的答案。 Log4J有一些记录解决方案。我已经让我的处理程序发送电子邮件,创建错误报告表单等......我将指定您需要执行的操作。一般来说录制错误是很好的做法。 – 2014-08-31 22:51:31

+0

简化部分,我想我可以弄明白。我只是试图在没有被捕获的情况下抛出错误时触发一个方法。之后,我简化它,让服务器所有者知道错误是什么(我将它编码为Bukkit插件)。你的代码中使用了 – ColonelHedgehog 2014-08-31 22:56:34

+0

- >'MyClass.doSomething(t,e);'你基本上是在“uncaughtException”方法上做的。你基本上可以做任何事情。 – 2014-08-31 23:12:36

回答

2

由于缺乏答案,但有很多讨论,可能发生的事情是您的框架设置了一个自定义处理程序,它吞噬了您的异常(例如几乎每个Web框架)。

下面是一些代码来说明它是如何工作的,因为有一个默认处理程序,然后每个线程或线程组都可以拥有自己的处理程序。

import java.awt.event.ActionEvent; 
    import java.awt.event.ActionListener; 

    import javax.swing.JButton; 
    import javax.swing.JFrame; 
    import javax.swing.SwingUtilities; 


    public class Tests 
    { 
     public static void main(String ... args) 
     {  
      Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() 
      { 

       @Override 
       public void uncaughtException(Thread t, Throwable e) 
       { 
        System.out.print("[Handler Handling]\t"); 
        System.out.print(t.getName()); 
        System.out.print("\n"); 
        e.printStackTrace(System.out); 
        System.out.println("[End Handling]"); 
       } 
      }); 

      new Thread() 
      { 
       { 
        //Disable this handler 
        this.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { 

         @Override 
         public void uncaughtException(Thread thread, Throwable throwable) { 
          System.out.print("[Different Handling]\t"); 
          System.out.print(thread.getName()); 
          System.out.print("\n"); 
          throwable.printStackTrace(System.out); 
          System.out.println("[End Different Handler]"); 
         } 
        }); 
       } 
       public void run() 
       { 
        throw new RuntimeException("This is thrown in the child thread."); 
       } 
      }.start(); 

      try 
      { 
       Thread.sleep(500); 
      } 
      catch (InterruptedException e1) 
      { 
       e1.printStackTrace(); 
      } 

      JFrame gui = new JFrame(); 
      gui.setSize(400, 300); 
      gui.setTitle("Swing Thread"); 
      JButton error = new JButton("Throw Error"); 
      error.addActionListener(
       new ActionListener() 
       { 
        @Override 
        public void actionPerformed(ActionEvent arg0) 
        { 
         throw new RuntimeException("This exception happens in the Swing thread"); 
        } 

       }); 

      gui.add(error); 
      gui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
      gui.setVisible(true); 

      throw new RuntimeException("This is thrown in the main thread."); 
     } 
    } 

这将提供以下输出(或类似的东西,如果你点击一个按钮):

[Different Handling] Thread-0 
java.lang.RuntimeException: This is thrown in the child thread. 
    at Tests$2.run(Tests.java:45) 
[End Different Handler] 
[Handler Handling] main 
java.lang.RuntimeException: This is thrown in the main thread. 
    at Tests.main(Tests.java:77) 
[End Handling] 
[Handler Handling] AWT-EventQueue-0 
java.lang.RuntimeException: This exception happens in the Swing thread 
    at Tests$3.actionPerformed(Tests.java:68) 
    at javax.swing.AbstractButton.fireActionPerformed(Unknown Source) 
    at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source) 
    at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source) 
    <...snipped for brevity...> 
[End Handling] 

所以这是不可能完全回答你的问题没有更多的信息。例如,如果您使用JavaFX,则处理未捕获的异常的模式有所不同。这完全取决于你的框架和情况。如果你实际上是在主线程上设置处理程序并从那里开始,那么这应该没有问题。