Java - How to properly handle a try catch block - java

I was wondering what is the proper convention for handling a try/catch block. It is pretty obvious what should be within the try block but what about the catch block?
Can I write a message to the user like the following:
do {
try {
System.out.println("Pi to the number of decimal places:");
Scanner in = new Scanner(System.in);
userNth = in.nextInt();
} catch (Exception e) {
System.out.println("Error: Enter a number between 1 and 100");
}
} while(userNth < 1 || userNth > piDecimals);
Or is this bad practice?

Exception-handling is not the place to make rash assumptions; usually by the time this part of your code has been executed it's because something unanticipated has happened, this is when you want to be most careful to be accurate about detecting and recording what happened so that you can tell what needs fixing.
The choice of Exception as the type of exception that gets caught is too broad. The method you're calling throws 3 different exceptions for distinctly different reasons; only one of which is something that should be caught here. Also unchecked exceptions like NullPointerException will get caught by this. If you were to add some code to this catch block that inadvertently introduced a NPE it would be hard to figure out what went wrong. Your overbroad catch can result in bugs not being found or errors not getting handled properly.
(Btw Makoto makes a good point that nextInt isn't what you should be calling here anyway.)
Not logging the exception can be acceptable in narrow cases where you're certain of what the exception means (for instance, if you caught InputMismatchException, or NumberFormatException in Makoto's example code). But in combination with catching Exception it has the capacity to hide errors and cause confusion.
You likely chose to catch Exception because handling a bunch of different checked exceptions, most of which seemed unlikely to ever happen anyway, seemed like an intolerable nuisance. Providing a consistent way of handling and logging exceptions will help, by providing a reasonable default case for exceptions you don't know what to do with. That way if you see an exception you just can't handle, you always have the option of letting it be thrown (possibly catching it and wrapping it in an unchecked exception), knowing that if thrown it will get logged and end your program.
For a very small command-line program sometimes it's entirely ok to let exceptions that you can't handle be thrown from main (by adding throws Exception to the main method). This is ok for toy examples, small school projects, etc.; I'd only use it in production code if there was a plan for logging the output (like a batch file that redirects stderr to a file):
public static void main(String... args) throws Exception {
... application code
}
In most cases all the main method code should be placed in a try block where any Throwable is caught and logged:
public static void main(String... args) {
try {
... application code here
}
catch (Throwable t) {
logger.log(t);
}
}
Either alternative makes it less tempting for you to inappropriately swallow inconvenient checked exceptions.

Simple Answer: what you wrote is fine
Longer Answer: try-catch blocks are for executing code that may throw an exception, and then handling said exception if it occurs. In general, the catch block should have code that handles the exception however you need to handle it. If the statement you currently have is how you want to respond to an exception, then it's fine by convention. Some common things to do in a catch block are:
Throw another exception that encapsulates the thrown exception. (I often do this when parsing so that there can be a single ParseException)
Throw a runtime exception encapsulating the thrown exception and let java's default uncaught exception handler deal with it. (I do this a lot when I'm writing quick temporary programs and I don't want to deal with checked exceptions)
Pass it to some generic handler in your program, such as a GUI to display the error, etc.
call printStacktrace on it
But anything that fits your exception-handling needs is fine

In all actuality, this code is not going to function the way you intend it to. There are two key reasons for this:
nextInt() blocks until it receives an integer; that is, it's not going to care about what input you give it until it reads an integer, and
Even if this were to be okay, depending on how you initialize userNth and piDecimals, one or both of those variables may not be defined, thus preventing compilation.
Also, don't catch Exception. Be as specific as you can when catching exceptions, since Exception also includes some nifty and dangerous RuntimeExceptions like NullPointerException.
What you're looking to do:
Take in an integer input
If the user enters a non-integer, tell them they need to enter an integer
Keep doing this while userNth < 1 || userNth > piDecimals.
To that, we should look to get the right exception thrown by parsing the input as a string first, then as an Integer:
try {
System.out.println("Pi to the number of decimal places:");
userNth = Integer.parseInt(in.nextLine());
} catch (NumberFormatException e) {
System.out.println("Error: Enter a number between 1 and 100");
// You have to set this value to something so that userNth is defined!
userNth = Integer.MAX_VALUE;
}
The other part to this is that you have to decide what message you show if userNth > 1 && userNth < piDecimals, since your try...catch isn't going to cover that. This, I leave as an exercise for the reader.

Related

Throwing an IllegalArgumentException isn't working

So, for a homework assignment, our professor wants us to try inserting an integer into an array of Strings:
public boolean addPerson(V person, int number)throws IllegalArgumentException{
if(numEntries < people.length){
people[numEntries] = person;
phones[numEntries] = number;
numEntries++;
return true;
}
return false;
}
public static void main(String[] args){
PhoneBook<String> names = new PhoneBook<String>();
PhoneBook<Integer> ssn = new PhoneBook<Integer>();
names.addPerson("john", 1235681213);
ssn.addPerson(123324567, 2048);
Integer soc = 132546789;
try{
names.addPerson(soc, 1996);
}
catch(IllegalArgumentException e){
System.out.println("You cannot enter a Social Security Number "
+ "into the Name phone book!");
}
But, this isn't working, and I still get the same error as without the try-catch. Any idea what I'm doing wrong?
EDIT
Sorry guys, I probably should've included the code for the addPerson method. I don't really know how to deal with exceptions yet.
What your professor likely wants you to observe is a compilation error. An array's type is fixed at instantation time, and will not change. The array will only ever accept whatever type it has been declared to accept, and nothing else.
Minor rant about exceptions to follow from here.
Let's have a quick chat about checked and unchecked exceptions. There is a difference between these two, and mixing them up can be painful at times.
Let's start with the checked exceptions. These are the exceptions that you must either explicitly catch yourself, or declare them to be thrown. Things along those lines are IOException, FileNotFoundException*, and a few others - pretty much anything that extends from the Exception class.
Java is telling you that you have the ability to recover from this error, and you as a good developer should ensure that your program does.
There are also unchecked exceptions; anything that extends RuntimeException or Error. These do not need to be declared to be thrown, as they occur during the runtime of the application, and there's really no guarantee if the program should recover from this error. An example of this would be ArithmeticException; should your application really recover if it tried to divide by zero? What state would it be in?
There are also some you really shouldn't be catching at all - what would you return to if you managed to catch an OutOfMemoryError? There isn't much you really can do at that point!
Now, to your code: you've declared an unchecked exception to be thrown. That's valid syntax, but Java isn't going to just arbitrarily throw the exception for you, because there isn't anything in that block of code that would just throw it. At worst, you could get an ArrayIndexOutOfBoundsException, but that's no IllegalArgumentException.
In order to actually throw that unchecked exception, you'd need to explicitly throw it:
throw new IllegalArgumentException();
...and you'd also need a good reason to do so. Exceptions are expensive.
*: I realize that FileNotFoundException is-an IOException. It's still checked.

How can I get a method to throw a custom exception I've created?

So my custom exception is PatternFormatException, and I've appended throws PatternFormatException, to the end of my method, but I'm wondering how I can actually get the method to physically throw it? Do I use if statements? i.e.
if //[doesn't_parse] throw PatternFormatException
This seems cumbersome for many different lines of code? Can I catch a more universal in built exception i.e. NumberFormatException, and then in the handling of this, throw my own exception?
You throw an exception using the throw keyword:
throw new PatternFormatException(...);
Generally you want to catch exceptions as early as they occur and handle them properly. If you want your parser (or whatever program you are writing) to generate meaningful errors, it's usually a good idea to wrap any caught exception and re-throw it, embedded in a more meaningful exception, giving the user a better idea of how things went wrong.
Something like this:
try {
doSomething(); // throws SomeException
doSomethingElse(); // throws SomeOtherException
}
catch (Exception e) {
throw new PatternFormatException(..., e);
}
generally is fine, if you know exactly what exceptions might happen and if all of them are properly encapsulated by PatternFormatException. However, the key idea of Exceptions in Java is that you are always aware of all the possible Exceptions that can happen. That is why Java forces you to add all possibly thrown Exceptions (except for RuntimeException) to the method declaration.
A safer design would be:
try {
doSomething(); // throws SomeException
doSomethingElse(); // throws SomeOtherException
}
catch (SomeException e) {
throw new PatternFormatException(..., e);
}
catch (SomeOtherException e2) {
throw new PatternFormatException(..., e2);
}
catch (Exception e3) {
throw new UnexpectedPatternFormatException(..., e3);
}
Note that the first two catches call different constructors, and thus can handle different Exceptions differently. The last catch wraps an unexpected exception because your program encountered an exception (probably a RuntimeException) that you did not plan for. If users then complain about UnexpectedPatternFormatException, you can just go back to your code and fix the code so that the underlying Exception either does not get thrown anymore or gets wrapped in a more meaningful way. You can also just use a single UnexpectedMySomethingException class as the fall-back for all try/catch blocks that you have, to keep things a bit simpler.
One last word should be said about issues caused by Exceptions: Even though, Java uses Exceptions for all kinds of situations, even those that are largely not in the control of the Java programmer (e.g. when accessing files or even trying to parse strings as numbers), always be aware that throwing and catching Exceptions is actually quite expensive, which is why many people tend to avoid that. Only really use Exceptions, if performance is not of an issue (when the Exception is a rare event).
Also, Exceptions can threaten the integrity of your program's state if you throw an Exception and catch it too late, so that lines that should have been executed did not get executed (e.g. code for cleaning up resources or other code that is needed to keep the program state "correct"), and, as a result, the only safe thing to do is to shut down the program.
If I understand your question correctly you could just do this:
If(somethingBad){
throw new PatternFormatException();
}
As stated in a response below. If your going to check this exception over and over again you might want some Static Method/Class Method (use your programming brain). For example you could do something like:
void checkForException(String pattern, String check){
If(!check.equals(pattern)){
throw new PatternFormatException();
}
}
Now all you have to do is:
try{
checkForException("abc","123");
}catch(PatternFormatException pfe){
System.out.println(pfe); //Whatever you want to happen if the exception is thrown
}
Remember though, ONLY use exceptions for exceptional situations...
Have a read over this for more information on exceptions. I find that I next to never use exceptions.

Exceptions in java, rethrown [duplicate]

This question already has answers here:
Why Re-throw Exceptions?
(13 answers)
Closed 9 years ago.
In some legacy code I see this, that an overbroad exception is being caught, and then thrown again, Is this a good practice? Does throw e; rethrow the same exception, or create a new one ?
catch (Exception e) {
StringBuilder sb = new StringBuilder(
"Oops. Something went wrong with id: ");
sb.append(id);
sb.append(". Exception is: ");
sb.append(e.toString());
System.out.println(sb.toString());
throw e;
}
throw e is rethrowing the same exception. At least it preserves the original stacktrace. It's just writing a message to stdout recording some information about what happened, then letting the original exception proceed on its way.
It's not a great practice, it should be enough to log the exceptions in a central place, recording their stacktraces. If you need to add more information (as in the example, where it logs an id), it's better to nest the original exception in a new exception as the cause, then throw the new exception. I would guess this probably occurs in contexts where there is no centralized logging or where exceptions tend to get eaten somewhere.
This is usually a bad practice. catch(Exception e) (sometimes called Pokemon Exception Handling for when you gotta catch 'em all) catches every single exception. Such exception handling is rarely useful because:
It catches runtime exception too.
You lose information about the type of exception that was thrown.
You cannot react to or handle specific exceptions.
Your method signature now is public void whatever() throws Exception, which is rarely useful. Now everything further up the chain has no idea what kind of exception you have thrown; they will have to do instanceof checks which defeats the purpose of catching specific-exceptions entirely.
As far as your second exception is concerned, throw e; throws the same exception object. If you wanted to wrap the exception, you can create a new one, which means you would do something like throw new MyCustomException(e);. You would also need to change your method signature.
If there is nothing further up the chain, I guess this isn't as bad (still isn't great, though). It looks like a method that is trying to log all exceptions that are thrown. However, again, there are better ways of doing this.
throw e does throw the same exception. There might have been reasons for doing this, but there is also a reason not to. In your example code, a message is sent to System.out, but if a stack trace were printed later on System.err, it won't be syncronized, and in fact the two might end up interwoven in your console.
A better approach would be the following:
catch (Exception e) {
StringBuilder sb = new StringBuilder(
"Oops. Something went wrong with id: ");
sb.append(id);
sb.append(". Exception is: ");
sb.append(e.toString());
throw new Exception(sb.toString(), e); // The original exception is an argument
}
This will create a new Exception with the modified message, and append the original Exception to the stack trace to help with debugging.
My best guess would be it is trying to have two layers of protection. Making sure that an error message is displayed and also asking the client to handle the exception the way it wants to because the catch clause is not doing anything to recover from the exception.
I won't consider it good/bad practice. Depending on your requirements you can consider to go either way like there might be 100 of different clients using your API and each one of them has a different way of recovering from an exception. By displaying what went wrong it is adding a default action layer just below the layer where client decides on how it will handle the exception.
Now back to your question. I think throw e throws the same exception object. As exceptions are objects in java you need to create a new exception object before you can throw it which I can't see happening in your code.
It can be a good practice. I think I always use conversion to RuntimeExceptions during prototyping. After this if there is a need one can change this into better exception handling. For this my purpose there is an utility class in Guava called Throwables which makes exception propagation.
In your case however the exception should be converted into a runtime exception, because declaring a method throwing a general Exception is just the same as a method throwing RuntimeException for the calling party. In the first case it 'catches everything', in the latter it 'catches anything'. I have not yet experienced the difference between two of these in real-world applications. So I prefer RuntimeExceptions as they require less typing.
Catching Exception
Checked exceptions (IO exceptions, security errors, concurrency, etc)
Runtime exceptions (anything, unpredicted garbage, see below)
Everything - these are 99% of all errors (there are Errors left however)
Catching RuntimeException
null pointer exceptions, index out of bounds exceptions, access exceptions, + API which wraps propagates exceptions into RuntimeException - this is ALSO A LOT
My point is after when you're catching an Exception you can't really handle all these cases. So it makes no difference except for the less typing for the calling party if you wrap it into a RuntimeException.

What is the good practice to terminate program in catch clause

I have a method throws an Exception
public int myMethod throws Exception
I have another function calls myMethod function and hava try-catch block.
I throws a runtime exception to enforce the program to be terminated.
Is this a proper way to terminate the program? If I do this way, it prints the stack trace twice and the stack trace from RuntimeException is useless.
What is the suggested way to terminate program in catch clause with printing the full stack trace.
public int callMyMethod(){
try{
myMethod();
}
catch(Exception ex){
ex.printStackTrace(System.out);
throw new RuntimeException();
}
}
The answer is "it depends".
If this code is part of the application itself then calling System.exit(int) is possibly the best option. (But if the application is "failing", then you should call exit with a non-zero return code. Zero conventionally means "succeeded".)
However, if there is a significant possibility that this code is going to be embedded / reused in a larger Java application, calling System.exit(...) is problematic. For instance a library that calls System.exit(...) when something bad happens is going to cause havoc for an application that uses it.
For something like that, you might throw a custom runtime exception which you catch and handle specifically in your main method. (If I was doing that, I'd pass the Exception as a constructor parameter to the custom exception ... and make it the cause exception. And I wouldn't print it / log it at that point.)
(Calling System.exit(...) also causes problems when you are unit testing ... 'cos the call will most likely pull the plug on the JVM running the test suite!)
The other point is that catch (Exception ...) is almost always a BAD IDEA. The point is that this catches just about everything (including all sorts of things that you never dreamed could happen!) and buries them. It is far better to catch the specific exceptions you are expecting (e.g. checked exceptions) and can deal with ... and just let the rest propagate in the normal way.
If you are stuck with catch (Exception ...) because you are using something that is declared as throwing Exception, the best way to deal with it is to change the throws Exception. And the sooner the better. Change the throws Exception to declare a list of (more) specific exceptions that you expect to be thrown by the method.
public int callMyMethod(){
try{
myMethod();
}
catch(Exception ex){
ex.printStackTrace(System.out);
System.exit(0); // terminates with exit code 0, no extra stack trace.
}
}
Exception handling is one of the most important aspects in programming.
The answer for your question depends on what type of application you are working on.
system.exit(0) will just terminate your program and this can create a lot of havoc .
Also make sure that you never catch Exception , if you are doing that then you are catching all the types of exceptions which you may not intend to handle also.
Always catch Specific exception such that it gives you opportunity to handle it in a manner which you need.

Try-catch: is this acceptable practice?

We have received Java code from a software supplier. It contains a lot of try-catch blocks with nothing in the catch part. They're all over the place. Example:
try {
spaceBlock.enable(LindsayModel);
} catch (Exception e) {
}
My questions are: Is the above acceptable practice? If so, when? Or should I just go ahead and remove all of these "bogus" try and catch statements?
To me this looks like terrible practice, but I'm not experienced enough in Java to tell for sure. Why catch errors if you're not going to do anything with them? Seems to me, you would only do that if you were confident that an exception would be of absolutely no consequence and you don't care if one occurs. However, this is not really the case in our particular application.
EDIT To give some context: We bought a Java-scriptable product from the supplier. Alongside the product, they provided a large proof-of-concept script tailored to our needs. This script came "free of charge" (though we wouldn't have bought the product if it hadn't come with the script) and it "works". But the script is a real pain to build upon, due to many things that even I as a Java novice recognise as awful practice, one instance being this bogus try-catch business.
This is indeed terrible practice. Especially the catching of Exception rather than something specific gives off a horrible smell - even a NullPointerException will be swallowed. Even if it is assured that a particular thrown exception is of no real consequence, one should always log it at the very least:
try {
// code
}
catch (MyInconsequentialException mie) {
// tune level for this logger in logging config file if this is too spammy
MY_LOGGER.warning("Caught an inconsequential exception.", mie);
}
However it is unlikely an exception is completely meaningless in this situation. I recommend researching exactly what exception(s) the application's code is intending to swallow here, and what they would really mean for the execution.
One important distinction is whether the try/catches are used to swallow checked exceptions. If this is the case, it probably indicates extreme apathy on the programmer's part - somebody just wanted his/her code to compile. At the least, the code should be amended:
try {
// code
}
catch (SpecificCheckedException sce) {
// make sure there is exception logging done farther up
throw new RuntimeException(sce);
}
This will rethrow the exception wrapped in an unchecked RuntimeException, effectively allowing the code to compile. Even this can be considered a bandaid however - best practice for checked exceptions is to handle them on an individual basis, either in the current method or farther up by adding throws SpecificCheckedException to the method signature.
As #Tom Hawtin mentioned, new Error(sce) can be used instead of new RuntimeException(sce) in order to circumvent any additional Exception catches farther up, which makes sense for something that isn't expected to be thrown.
If the try/catch is not being used to swallow checked exceptions, it is equally dangerous and should simply be removed.
Terrible, indeed. Swallowing an exception like this can be dangerous. How will you know if something bad has happened?
I'd feel better if the vendor wrote comments to document and acknowledge it ("We know what we're doing"). I'd feel even better if there was a strategy apparent in the code to deal with the consequences. Wrap it in a RuntimeException and rethrow; set the return value to an appropriate value. Anything!
"All over the place"? Are there multiple try/catch blocks littering the code? Personally, I don't like that idiom. I prefer one per method.
Maybe you should find a new vendor or write your own.
try {
meshContinuum.enable(MeshingModel);
} catch (Exception e) {
}
This looks like unfinished code. If the enable method throws an Exception then it will be caught and swallowed by the code. If it doesn't then it does not make sense to try to catch a non occuring exception.
Check to see the methods and where their signatures are not followed by throws exceptionName, then remove the empty try-catch statements from the places they are called.
You can theoretically put try-catch around any statement. The compiler will not complain about it. It does not make sense though, since this way one may hide real exceptions.
You can see this as a sign of bad code quality. You should probably be prepared to run into problems of different type too.
It's not the best:
It hides evidence of the exception so debugging is harder
It may cause features to fail silently
It suggests that the author might actually have wanted to handle the exception but never got around to it
So, there may be cases where this is OK, such as an exception that really is of no consequence (the case that comes to mind is Python's mkdirs, which throws an exception if the directory already exists), but usually, it's not so great.
Unfortunately you cannot just remove it, because it the try block throws a checked exception then it will have to be declared in the throws clause of the method. The callers of the method will then have to catch it (but not if the callers also have this catch (Exception e) {} abomination).
As an alternative, consider replacing it with
try {
meshContinuum.enable(MeshingModel);
} catch (Exception e) {
throw (e instanceof RuntimeException) ? (RuntimeException) e : new RuntimeException(e);
}
Since RuntimeException (and classes that extend it) are unchecked exceptions they do not need to be declared in the throws clause.
What did your contract with the supplier specify? If what they wrote, bad practice and all, meets the spec then they will charge you for a rewrite.
Better to specify a set of tests that will enter many or all of those try-catch blocks and hence fail. If the tests fail you have a better argument to make them fix their terrible code.
Horrible idea on the face of it, totally depends on what you're actually calling. Usually it's done out of laziness or habituated bad practices.
Actually ... not so fast.
There are legitimate cases for ignoring an exception.
Suppose that an exception has happened already, and we're already in a catch(). While in the catch(), we want to make best effort to clean up (which could fail, too). Which exception to return?? The original one, of course. The code looks like this:
try {
something-that-throws();
} catch(Exception e) {
try {
something-else-that-throws();
} catch(Exception e1) {}
throw e;
}
When we really don't care whether an operation succeeds, but (unfortunately) the operation's author throws an exception if a failure occurs.
if (reinitialize) {
try {
FileUtils.forceDelete(sandboxFile); // delete directory if it's there
} catch(Exception e) {}
}
The above saves a rather tortured attempt to see if sandboxFile actually exists before deleting it anyway.

Categories

Resources