Locked History Actions

GWT/ExceptionHandling

例外処理

クライアント側で発生した例外を放置しておくと、何のメッセージも出さずに単純に機能不全に陥いる。 Firebugのコンソールでこれを確認することはできるのだが、次の問題がある。

  • ユーザ側でFirebugを開いて例外を確認することは困難。
  • この際のスタックトレースは難読化されているので、意味不明。

以下では、クライアント側で例外が発生したら、それをサーバ側に送り、難読化を解除して適切なスタックトレースを表示させる方法を示す。

ビルド・設定ファイルの変更

gwtcコンパイル持にシンボルマップを作成させる

難読化解除のためには、シンボルマップ、つまり元の名前と変更された名前のマップが必要。 これはgwtcコンパイラに「-extra war/WEB-INF/classes/」という引数を指定してやる必要がある。 antで行っている場合は以下。

  <arg line="-extra"/>
  <arg value="war/WEB-INF/classes/"/>

gwt.xmlファイルの変更

以下を追加する。

  <set-property name="compiler.stackMode" value="emulated" />
  <set-configuration-property name="compiler.emulatedStack.recordLineNumbers" value="true" />

プログラムの変更

クライアント側

public class Sample implements EntryPoint {
  
  @Override
  public void onModuleLoad() {
    
    // キャッチされていない例外のハンドリング
    GWT.setUncaughtExceptionHandler(new  ClientExceptionLogger());
    
    ...
  }
  ...

  private class ClientExceptionLogger implements GWT.UncaughtExceptionHandler {  
    
    @Override
    public void onUncaughtException(Throwable th) {        
      th = unwrap(th);
      StackTraceElement[]elements = th.getStackTrace();

      // elementsをサーバ側に送信する。
      // 例外オブジェクトそのものを送信しようとすると、色々面倒くさい。
    }
    
    private Throwable unwrap(Throwable e) {   
      if(e instanceof com.google.gwt.event.shared.UmbrellaException) {   
        UmbrellaException ue = (com.google.gwt.event.shared.UmbrellaException) e;  
        if(ue.getCauses().size() == 1) {   
          return unwrap(ue.getCauses().iterator().next());  
        }  
      }  
      return e;  
    }      
  }

サーバ側

参考資料