The leJOS Tutorial

| Start of Tutorial > Start of Trail

Trail: Essential leJOS classes
Lesson: Finding errors

# Finding errors

As you undoubtedly know, error handling is a very comfortable thing in Java because of the

                try {
                    ...
                } catch(Exception exc) {
                    // handle exception here
                } // catch

mechanism.
Finding uncaught exceptions is pretty easy, too, for the in this case virtual machine will display the `Exception`'s stack trace, so you can easily identify the program's flow which led to the error in question.

You are able to use the try-catch mechanism with leJOS also.
For uncaught exceptions, however, the process of finding errors isn't as easy as you are used to due to the fact that the RCX is limited to five characters which can be displayed at a time.
Hence the process of stack tracing is different when such an exception occurs on the RCX:
You will see two number on the RCX's display, separated by an "^", e.g.

                0074^5

What does that mean?
The first number is the (signature) number of the method the exception occurred in, the second number is the id of (exception) class that was thrown mod 10.

Now how do you assign those number to some actual method or exception, resp.?
A list of all the classes, methods and exceptions which are used in the actual leJOS program can be obtained by calling `lejoslink` with the `-verbose` option:

                lejoslink -verbose [main class]

You will get an output the likes of this one:

                Class 0: java/lang/Object
                Class 1: java/lang/Thread
                Class 2: java/lang/String
                Class 3: java/lang/Integer
                Class 4: java/lang/Boolean
                Class 5: java/util/Date
                ...
                Class 15: java/util/Vector
                Class 16: josx/platform/rcx/Motor
                ...
                Class 22: MyMainClass
                Class 23: josx/platform/rcx/Sensor
                Class 24: java/lang/NullPointerException
                Class 25: java/lang/ArrayIndexOutOfBoundsException
                Signature 0: main([Ljava/lang/String;)V
                Signature 1: run()V
                ...
                Signature 74: getElement()V
                Signature 75: hashCode()I

Examining the first number 0074, we can easily detect that the error occurred in the `getElement()` method.
The second number is 5, so the exception class that was thrown is one of the classes above with last cipher 5; it is easily guessed that there is only one such candidate, namely `java/lang/ArrayIndexOutOfBoundsException`.

Even if there is more than one exception class with the same trailing cipher, usually the exception that was actually thrown can be guessed by the content of the method it was thrown by.

## Assertions

Since leJOS version 2.1.0, there is the `josx.util.Assertion class available, which implements a pattern known from Java 1.4 or JUnit:
a boolean condition is checked to be true; if it fails, the program's flow is stopped and an error is thrown, else the program continues.
This is rather useful for debugging and testing: if you want to assure that your program complies with some condition at a certain point of code, use an assertion there.

`josx.util.Assertion` offers two static methods to complete that task:

- `public static void test(String anErrorMessage, boolean aCondition) throws Error` throws a `java.lang.Error` with the given error message, if the condition is false
- `public static void testEQ(String anErrorMessage, int anExpectedValue, int anActualValue) throws Error` throws a `java.lang.Error` with the given error message, if the the actual value is not equal to the expected one.

So an actual call might look like this:

                try {
                    ...
                    // maybe a light sensor
                    int light = Sensor.S1.readValue();
                    Assertion.test("it's too dark around here",value>100);
                    // maybe a touch sensor
                    boolean notTouched = Sensor.S2.readBooleanValue();
                    Assertion.test("ouch!",!notTouched);
                    // maybe some computation
                    int expectedValue = 37;
                    int computedValue = computeSomething();
                    Assertion.testEQ("unexpected value",37,computedValue);
                    ...
                } catch(Error error) {
                    // do something here
                } //catch

Note that the actual behavior of an assertion is platform dependent:
For the time being, if a `josx.util.Assertion` fails on Windows, it will just throw an Error, whereas on UNIX the error message is printed to standard out additionally.

The leJOS Tutorial

| Start of Tutorial > Start of Trail

`