Reputation: 59
This is my program structure:
main function -> call Class A obj -> Class A calls Class B obj
when it comes to exception handling, I want to exit the program with error code if exception is encountered either in main, class A or class B.
Currently, I am doing what I feel is a cumbersome process (and likely a foolish way):
-> Have exception handling within the functions of Class A and Class B.
-> Have the function exit with a value deemed 'error' (such as specific value or boolean false) if exception occurred in function.
-> main has its own try/catch but also for each function call of class A and class B, if it return is 'error', it throws exception and then exits with error code.
My contention with this approach is (a) I am throwing and handling exception potentially multiple times (at the class level and then at main level). (b) If a function in class is suppose to return a value, than I have to set aside a specific value that when received, should be interpreted as error.
any cleaner suggestions? This is for programs which will be compiled to run as executable JAR from command line and won't be a micro service (or web server based -- for those, I reckon, instead of exiting the program, you would report the error in log and continue on).
Upvotes: 0
Views: 392
Reputation: 18577
Generally speaking, it's only worth catching and re-throwing an exception if:
finally { }
block).If you're not doing any of those, then go for the easy way out and don't catch the exception. But do mention it in the method's JavaDoc, even if it's unchecked.
And as others have said, returning a dedicated error code is rarely a good idea in Java; they're wordy, easy to forget, and don't propagate to the caller. And returning a special value (e.g. null
) in place of a normal return value is even worse! Exceptions are the standard way, and that's what everyone will be expecting.
Upvotes: 1
Reputation: 35011
The thing about Exceptions in Java is that they do a lot of different things, semantically
Errors in code: Exceptions like NullPointerException or SQLExceptions where your SQL isn't right. These (IMO) shouldn't be caught, or should be rethrown as Errors and caught in the uncaughtExceptionHandler (which you can define in Thread)
User errors: Exceptions like NumberFormatException and exceptions on bad form data, where the user has entered invalid values. This (IMO) should be handled in place with a message near where they should correct the value
Normal, expected exceptions: Exceptions like IOException / SocketException. InterruptedException is in this family too. These Exceptions are your friends(!), as they unlock the threads that are waiting on something that they should be waiting on anymore. They are part of the normal cycle of connecting to IO resources. So if a socket closes, you could log the exception somewhere (sometimes even that isn't necessary), and possibly ask the user if they want to reopen the connection.
Upvotes: 1
Reputation: 41625
The basic idea you should follow is to have a main
method like this:
public static void main(String... args) {
try {
new A().run();
} catch (ExitProgramException e) {
System.exit(e.getCode());
}
}
There is no predefined ExitProgramException
yet. This is good, since otherwise some other class could already throw it. In this case though, you want to define all the places where this exception can be thrown. The exception class should be defined as follows:
public final class ExitProgramException extends RuntimeException {
private final int code;
public ExitProgramException(int code) { this.code = code; }
public int getCode() { return code; }
}
Now, in classes A and B, you can throw new ExitProgramException(1)
, and everything will work as intended.
Because of the extends RuntimeException
, the intermediate code does not have to know about this exception and will happily let it bubble through, from class B over class A back into the main
method, where it is finally caught and converted into the exit code.
Upvotes: 1
Reputation: 1678
IMHO either use exceptions or error code as return value and be consistent with that approach.
In kotlin you can use powerful libraries as Arrow-kt which offers you some sofisticated types to handle errors like Try or Either to handle respectively exceptions and error codes or states.
Disclaimer: I am not affiliated with Arrow team
Upvotes: 0
Reputation: 973
Return values should NOT be used for signaling errors to the caller. In JAVA you would just throw an exception.This is a core feature.
What you are actually interested in is how to signal an error state to the command line. So, for class A and class B, use standard exception throwing. However, within the main method you might exit abnormally for some exceptions or maybe even all exceptions. Please check How exactly works the Java application exit code of the main() method? for more details.
Upvotes: 0