Nerian/akephalos2 — pull request #28 by orlanthi (2012-04-05 06:05:19+00:00)
Title: Improved NativeException handling

Hi Nerian,

The other day I was having a problem with a failing capybara test using akepalos. The somewhat cryptic output was:

And I press "Finalise Selected" # features/step_definitions/web_steps.rb:27
java.lang.NullPointerException: null (NativeException)
./features/step_definitions/web_steps.rb:29:in `block (2 levels) in '
./features/step_definitions/web_steps.rb:14:in `with_scope'
./features/step_definitions/web_steps.rb:28:in `/^(?:|I )press "([^"]*)"(?: within "([^"]*)")?$/'
features/wba/results/09_amc_approves_results.feature:28:in `And I press "Finalise Selected"'

Unfortunately, I had no chance of trying to work out what the cause of the failure was because the Java stack trace was lost.

After some digging around (including downloading, modifying, and compiling the HtmlUnit source), I found out what my problem was. However, if this sort of issue occurs sometime again in the future I don't want to have to repeat the process to find out what's wrong. Having finally seen the Java stack trace I realised my journey would have been shortened significantly if I'd had access to it in the Ruby backtrace.

This pull request is for some modifications which allow us to see the full Java stack trace as a Ruby backtrace.

The main issue I had to solve is that when akephalos received a NativeException on the server side and then passed it through to the client side, we lost the ability to access the NativeException's data (including the backtrace), due to the missing NativeException class on the plain (non-JRuby) client - this is of course why NativeException needs to be defined in remote_client.rb.

The solution I took was to convert NativeExceptions to an exception class guaranteed to be on both sides of the link, namely RuntimeError. I did this by wrapping Node and Page instances using a SimpleDecorator extension. (Now I think of it, I don't think I actually needed to wrap Pages but since they're one of the 'remote' classes I thought it worthwhile. Maybe this one should be undone or maybe the other remote classes should be similarly wrapped?)

Now the stack trace information comes through as follows:

And I press "Finalise Selected" # features/step_definitions/web_steps.rb:27
NativeException java.lang.NullPointerException: null (RuntimeError)
(druby://127.0.0.1:63662) com/gargoylesoftware/htmlunit/html/HtmlForm.java:112:in `submit'
(druby://127.0.0.1:63662) com/gargoylesoftware/htmlunit/html/HtmlSubmitInput.java:75:in `doClickAction'
(druby://127.0.0.1:63662) com/gargoylesoftware/htmlunit/html/HtmlElement.java:1244:in `click'
(druby://127.0.0.1:63662) com/gargoylesoftware/htmlunit/html/HtmlElement.java:1195:in `click'
(druby://127.0.0.1:63662) com/gargoylesoftware/htmlunit/html/HtmlElement.java:1158:in `click'
./features/step_definitions/web_steps.rb:29:in `block (2 levels) in '
./features/step_definitions/web_steps.rb:14:in `with_scope'
./features/step_definitions/web_steps.rb:28:in `/^(?:|I )press "([^"]*)"(?: within "([^"]*)")?$/'
features/wba/results/09_amc_approves_results.feature:29:in `And I press "Finalise Selected"'

Regards,

Brendan