例外処理
クライアント側で発生した例外を放置しておくと、何のメッセージも出さずに単純に機能不全に陥いる。 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; } }
サーバ側