HowTo catch exceptions or Who eats the StackTraces ?

you just added some fields to your Screen and now the Screen won’t be pushed anymore.

does this sound familiar to yoo ?

as you know there’s no Console output while running a BB App without debugger attached, so it’s not easy to know what happens. Attaching the Debugger may take some time in complex environments so I always try to avoid those wasted time. That’s the reason why I’m using an own LoggingFramework – but thats another story.

Even Logging or Debugger doesn’t help immediately if you don’t catch Exceptions and print them.

So we want to take a deeper look how you can help yourself to make your App more robust from the beginning and not only per accident. In many cases perhaps you made a mistake while copy/paste some code. This is why I always hate copy/paste-development and like to generate code a model-driven way. but thats also another story. (you see there will follow many blog entries around BlackBerry development next months😉

… perhaps it happens while adding some Fields to a Manager, so lets take this as an example:

Taking a look at the JavaDoc it seems easy and you surround you code with a try/catch and you catch the IllegalStateException and the IllegalArgumentException.

You restart your App, but same as before: the Screen wasn’t pushed.

hmmm – perhaps another Exception happens ? You also catch Exception and print e.getMessage() and restart your App:

now something happens: an Exception was caught and a Message was printed ! … but the Message was ‘null‘ – so not really helpful😉

You add printStackTrace and attach the Debugger – but no StackTrace was printed. (see below)

But you can get more out of this situation:

at first its a good rule to catch Throwable instead of Exception if developing BB Apps. (more infos at the end of this entry)

as next add the Class of the caught Throwable to get more informations and always add the message – but maybe the message is null.

BTW: my logger.error method also does a printStackTrace.

here’s the output from my LoggingMonitor (Lilith):

Now we know, its a NullPointerException. Because your Screen now was displayed, take a look at the last added Field and you know which Field is null. You’ll see that you forgot to create this Field.  You can now explicitely react on different situations: IllegalStateException if you tried to add a Field a 2nd time to Manager, IllegalArgumentException if you try to add the Field to itself and Throwable for all other cases. The good thing: the Screen will always be displayed.

Lets make a test what happens if you add a Field twice to the Manager:

Now we expect the IllegalStateException – and really this one was caught:

The IllegalStateException was caught and this time we also have a Message: “Field added to a Manager while it is already parented“.

Rules HowTo Catch: If you have to distinct between the different Exceptions, then catch all of them and as last Throwable – if you always react the same, then you only need to catch Throwable, but never forget to catch Throwable: it will save you much time.

Perhaps you’re wondering why printStackTrace didn’t work in the example above  ? It’s the same reason why we have to use Throwable – here’s from the JavaDoc of Throwable – and no, its no april joke:

RIM Implementation Note
Only uncaught exceptions have stack traces. The VM checks the current catch stack and if it finds anything that will catch the exception, it eliminates the stack trace to save time and memory. Any code in the current stack such as catch (Exception e) eliminates the stack trace.
If the exception is never caught, then the stack trace is generated.The stack trace is also generated if there is code such as catch (Throwable t).

Please read it again: if you catch an Exception, the RIM VM removes the stacktrace ! Only if you catch Throwable, the StackTrace is available – you can get this StackTrace while debugging or from the EventLog of the Device, but its not as readable as you know from ‘normal’ Java. For me a good logging and adding all informations YOU have while catching an Exception can help. You can also follow this Thread at BB SupportForum.

We have to add to our rules: If you need the StackTrace, don’t catch Exceptions – only Throwable have StackTraces !

You want to take a look at a StackTrace from the Devices Event Log and don’t find it from the Menus ? There IS no menu – you have to hold down the ALT key and then type

LGLG

as secret command. this will give you access to the Event Log.

Here’s what you’ll get from this Event Log in the first use case where we added an undefined Field (null) to the Manager:

…and here are the details:

and so on until you reach the end of the StackTrace.
…..
hint: all work was done using BlackBerry Java SDK 5.0.0.25, Eclipse PlugIn 1.1.2 and tested using Devices + Simulators on 9700 + 9550

back to the overview

if you like my work, you can Flattr this

6 responses

  1. Another reason to have issues with pushing a screen is you overwrote .isFocusable in the first “focusable” field (or manager) and then don’t actually allow something to take focus.

    • thx for mentioning this. …. I only used add(field) because I needed an easy to follow example what can happen while catching Exceptions😉

  2. A little tip aside: Exception.getMessage() is many times null or empty for RIM exceptions when they are thrown by RIM methods. But Exception.toString() does tell it’s type and the message, if it has any. So I found it more hassle-free to just print(e) instead of using my own “e.getClass() + e.getMessage()” code.

    Often the type tells you much more when you would expect…

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s