Exception Handling Best Practice

We are using java with a command based robot. I wondering how others are handling java exceptions… do you try-catch exceptions in the public subsystem methods, command methods, or just let the framework handle them?

In general, I’m just trying to prevent a total meltdown if I don’t catch something.

Use try-catch. But most importantly, keep them separate, and put them at the end of any piece of code that only runs once.

That way, if the camera suddenly gets unplugged during a competition, your robot won’t just sit there and wait until it gets image.

Here’s a (very real) example of what might cause problems:


public void robotInit(){
    try {
        // camera init code
        // joystick init code
        // jaguar init code
    } catch (Exception ex){
        ex.printStackTrace();
    }
}

If your camera code is broken, the joystick and jaguar init code will not execute, and your robot will not run. The solution is to take the joystick and jaguar init code out of the try-catch.

Try-catch blocks aren’t a cure for cancer, or robot crash. What you want to do with try catch is to make sure that you’re anticipating possible errors, like camera taking time to boot up before it’s ready to get image, components breaking in the middle of a competition, wires becoming unplugged.

You want to make sure that if something is broken, everything else (that doesn’t depend on it) still works. THAT, I believe, is the point of catching exceptions.

Some people might take issue with me try-catching using a general exception, but I disagree and would actually recommend that for competition. You want to make sure nothing silly escapes your try-catch and crash your robot.

While you shouldn’t ignore the exceptions which crop up, that doesn’t mean you have to handle them - when possible, I just declare them as thrown all the way up to the top. If something happens, it will crash the robot.

This might sound like a bad thing, but the common exceptions, like those thrown by the functions to create an AnalogChannel, etc, are configuration problems and wouldn’t be likely to be recoverable anyway.

The other common one is InterruptedException. You might not be able to throw it (if you get one in the inhereted method of Runnable.run()), and in this case, you should feel safe just eating it - catch it and do nothing. The only thing that will generate an InterruptedException on the cRIO would be user code, as in, you would have to explicitly interrupt that thread for it to happen.

When in doubt, just throw it.

Thanks for the input. I’ve updated our code to try-catch during the init process as Patrick mentioned and throw when there is something catastrophic. One of the reasons I asked was for the CANTimeoutException. We are using CAN and most methods on the CANJaguar throw this exception so we have try-catches everywhere. Don’t know if there is anything to do with this… I just increment an error counter and display it to the SmartDashboard. Oddly enough the place I get most of these CANTimeoutExceptions is in the updateStatus() method used to send data back to the SmartDashboard.