2014-08-31 58 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,則處理未捕獲的異常的模式有所不同。這完全取決於你的框架和情況。如果你實際上是在主線程上設置處理程序並從那裏開始,那麼這應該沒有問題。