GWT SuperDevMode and Pause on uncaught exceptions

Recently I've switched to SuperDevMode one of my pet GWT projects.

The main reason was - GWT have problems with Development Mode plugin for modern browsers.
More details:



The modern replacement of Development Mode is Super Dev Mode.
It is different, but in many ways - just remarkable solution! Take you time to get more into it.

Pause On Uncaught Exceptions

Anyway, Super Dev Mode have some gotchas.
One of recent I faced with - "Pause on uncaught exceptions" in browsers debugger (like in Chrome).

The situation 

I want to use "Pause on exceptions" of Chrome browser, but it don't work or provide no exception stacktrace.

First step - No UncaughtExceptionHandler 

Switch off my UncaughtExceptionHandler in EntryPoint of my app. Once done - browser starts stop on exceptions.
Okay. But, I always stop in one place - "entry" method of com.google.gwt.core.client.impl.Impl.java in gwt-user.jar!
Looking at source of this method you my see that ANY exception will be wrapped...for...NO..reason.
 
  public static native JavaScriptObject entry(JavaScriptObject jsFunction) /*-{
    return function() {
      try {
        if (@com.google.gwt.core.client.GWT::isScript()()) {
          return @com.google.gwt.core.client.impl.Impl::entry0(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)(jsFunction, this, arguments);
        } else {
          var _ = @com.google.gwt.core.client.impl.Impl::entry0(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)(jsFunction, this, arguments);
          if (_ != null) {
            // Unwraps for Development Mode (see #apply())
            _ = _.val;
          }
          return _;
        }
      } catch (e) {
        // This catch block is here to ensure that the finally block in entry0
        // will be executed correctly on IE6/7.  We can't put a catch Throwable
        // in entry0 because this would always cause the unhandled exception to
        // be wrapped in a JavaScriptException type.
        throw e;
      }
    };
  }-*/;
Yes, I see big comment about some issue under IE6/7, but... IE6/7 support was dropped in GWT 2.6.

Meanwhile, that brutal try-catch still in place.


In fact, there is a trick to get original stacktace - execute "console.error(e.stack)" - this will drop original stacktrace into console, thus, It may be obfuscated.

Step two - Get rid of exception wrapping.

To move forward - we should get rid of that try-catch. Only in this case debugger is correctly stop on needed exception, and you will be able to see stacktrace, arguments, variables, etc in that place.
To do so, we need - hack GWT :). No, kidding, just replace implementation on Impl.java to modified one which have no try-catch. 
Like following:

 
  public static native JavaScriptObject entry(JavaScriptObject jsFunction) /*-{
    return function() {
        if (@com.google.gwt.core.client.GWT::isScript()()) {
          return @com.google.gwt.core.client.impl.Impl::entry0(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)(jsFunction, this, arguments);
        } else {
          var _ = @com.google.gwt.core.client.impl.Impl::entry0(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)(jsFunction, this, arguments);
          if (_ != null) {
            // Unwraps for Development Mode (see #apply())
            _ = _.val;
          }
          return _;
        }
    };
  }-*/;
TODO: Possible, I need to file a bug, suggestion or patch to GWT team about of such change.

Instruction about replacing on some class of gwt-user.jar I found in GWT forum.
In short, you need only copy source of Impl.java, modify it, and than put it into you project to Gwt compiler can see it.
For my case - I've already have "super-source" folder in my project, so I've just put  modified com\google\gwt\core\client\impl\Impl.java to this folder.

Compiling..and...bingo!

Now the debugger stops on my real exception - NPE in my code:

PS: Here how modified Impl.java appears in stacktrace:


Happy debugging!

Comments