Java Try Catch Block Size - java

This might be a weird question, but I still thought I would ask to get insights into this, and stop me from doing something wrong while I am coding.
Let's say I have a function func1(), inside which I call a function func2(). func2() throws an exception e1. And I want to catch this exception inside func1().
So does it matter whether I start a try block at the beginning of the function itself and end it at the end of func1() with the catch block, rather than just surrounding the part of the code where I call function func2().
I know from the coders perspective, where if an exception is thrown, he will be able to know exactly where the exception came from. If we ignore this, are there any other ill effects of just placing the whole method inside try-catch?
Edit - Code Fragment
So I am converting a JSON String to JSON Node. This operation throws an exception. But instead of surrounding this one statement with a try-catch block, I put the whole function inside the try block. It just looks cleaner to me. :)
public void storePublicData(String publicData, String twitterId) {
try {
Date date=new Date();
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
String day = formatter.format(date);
BasicDBObject query = new BasicDBObject("date", day);
query.append("brand_id", twitterId);
JsonNode publicDataJsonNode;
publicDataJsonNode = JSONOperations.castFromStringToJSONNode(publicData);
DBObject document = BasicDBObjectBuilder.start()
.add("brand_id", twitterId)
.add("date", day)
.add("followers", publicDataJsonNode.get("followersCount").asText())
.add("tweets", publicDataJsonNode.get("tweetsCount").asText())
.get();
twitterCollection.update(query,new BasicDBObject("$set", document), true, false);
} catch (JSONParamsException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

The biggest disadvantage is that you may also catch an exception you didn't intend to catch.
For instance, let's say you have a method that may throw a NullPointerException, and you can handle that case. (Such a method is probably badly written, but let's say it's a library method and you can't change it.) So, you catch the NPE:
void func1() {
try {
func2();
if (someString.equals("some value") {
someOtherFunction();
}
} catch (NullPointerException e) {
// handle func2()'s NPE somehow
}
}
There are two places a NPE could have been thrown within the try's body: from func2, or from someString.equals if someString is null. This code treats both the same way, which is probably a bug.
Generally speaking, in nearly all aspects of programming (variable scope, try-catch blocks, class members, etc), the smaller the scope is, the easier it is to reason about and the less likely you are to write bugs.

You can obviously use a try/catch block surrounding the entire body of the method, but confining it to the area that you are expecting an error adds readability to your code. I'm also fairly certain that they are very slow, and inefficient and there's no point to 'try' something where there's no possible IOException for example int i = 2 + 2;

I know from the coders perspective, where if an exception is thrown,
he will be able to know exactly where the exception came from
You nailed it right there: when you write a method you create a contract between you and the user. If you declare that the method throws an exception - it will be the responsibility of the user to catch and handle that exception. If it makes sense - you should do it (for example, throw an exception if you failed opening a connection to the DB). That said, in other cases, you might want to preform a fallback and just report to the user if the action was successful or not, in that case you can surround all the code inside method2 with try/catch and return a boolean value to save your users the extra coding of handling the exception.

well, if you have anything in funct1 after the call to funct2, that won't get executed if you place the whole method inside the try-catch.

im am citing Clean Code Book :
Error Handling Is One job, and functions should do one job.
Thus, a function that handles errors should do nothing else. This implies (as in the example above) that if the keyword try exists in a function, it should be the very first word in the function and that there
should be nothing after the catch/finally blocks.
so you should create a method that manages the exception , something like this:
public class Test {
public void doSomthing(){
// here i don't need to manage the exception because i have built parseDate(String date)
Date date = parseDate("10-17-2016");
}
private Date parseDate(String date){
Date result = null;
try {
result = new SimpleDateFormat().parse(date);//Throws Parse Exception
} catch (ParseException e) {
// Here you can:
//1) Throws other exception (Checked or Unchecked)
//2) Log the exception
// I think you should not re-throws the exception because
//is responsibility of this methods manage the exception
e.printStackTrace();
}
return result;
}
}

Related

Java: How to propagate a "method exit" when tucking-in exceptions?

By "method exit" - I mean the actions in a method such as return or throw new... that the compiler considers the end of a method - if you could please tell me the accepted word for "method exit", I will edit the question
My problem is the following:
I do a lot of throw new RuntimeException(...
So, I decided to "tuck it in" as:
public static void quickRaise (String msg) { throw new RuntimeException(msg); }
And then I can reuse it.
(This will help me in the future to enhance the procedure around raising Runtime Exceptions and even
switch to a custom Exception class, without fishing in the code for exception throws)
However, where before I could write:
public MyType doSomething() {
try {
//...
return new MyType (parameter);
} catch (Exception e) {
throw new RuntimeException("msg")
}
}
And the compiler would correctly understand that "this method either exits by return or by throw" and therefore there are no logical "dead ends"
When I changed throw new RuntimeException("msg") to quickRaise("msg"), the compiler no longer considers my method "complete". It complains about a missing return statement, even though quickRaise is semantically equivalent to throw (or at least this is what I am trying to do!)
Let me try to reiterate the problem by a reproductive example (this will not compile, which is the problem):
public static void main(String[] args) {
System.out.println(doSomething());
}
public static String doSomething () {
try {
//... Some fun stuff going on here
return "Something";
} catch (Exception e) {
quickRaise("Could not find handshakes");
//throw new RuntimeException("If you uncomment this line, it will compile!");
}
}
public static void quickRaise (String msg) {
throw new RuntimeException(msg);
}
Your idea is highly inadvisable.
For example, this is just bad codestyle:
try {
someIO();
} catch (IOException e) {
throw new RuntimeException("Problem with IO");
}
The reason it's bad is that you have now obliterated the actual information about the problem. That information is locked into 5 separate parts of that exception you just caught: Its type (for example, FileNotFoundException, its message (e.g. "Directory /foo/bar does not exist"), its stack trace, its causal chain, and as throwables are objects, any particular extra detail for that particular kind of exception (such as the DB-engine-specific error coding for some SQLException).
Throwing this info away is silly.
All you'd need to do to fix this, is to add the cause:
} catch (IOException e) {
throw new RuntimeException("IO problem", e);
}
Now the IOException is marked as the cause of the exception you are throwing, which means in error logs you'll see it + the message + the stack trace of it + the stack trace of any causes it had as well.
All you need to do to make the compiler realize that the method ends here, is to throw it:
public static RuntimeException quickRaise(String msg) {
throw new RuntimeException(msg);
return null; // doesn't matter, we never get here
}
// to use:
throw quickRaise(msg);
But, as I explained before, this is a very bad idea.
Secondarily, having the idea of 'I just want to throw an exception and maybe later I want to replace the kind of exception I throw' also doesn't really work out: You need to pick a proper exception for the situation, therefore you cannot write a one-size-fits-all throw method in the first place.
Okay, so what do I do?
Primarily, learn to embrace throws clauses. If your method fundamentally does I/O (for example, the javadoc of it and/or the name makes that obvious, it is for example saveGame(Path p), or scanUserHome), then it should be declared to throws IOException.
If your method is an entrypoint (as in, it is the first point where your own code begins running), then your method should be declared to throws Exception. For example, your public static void main() method should throws Exception. Sometimes an entrypoint isn't main but something else (a webhandler routing hook for example), and sometimes backwards silly franeworks prevent you from doing that, but there tends to be a wrap functionality (such as } catch (Exception e) { throw new ServletException(e); }).
For exceptions which are both [A] fundamentally not part of the method's purpose, but more part of an implementation detail and [B] is very unlikely to go wrong and there's not much you can do other than hard crash if it would, then, yeah, rewrap as RuntimeException. There isn't a lot of point in ever changing this 'globally' for all such exceptions. At best you belatedly realize that failure is a bit more likely than you originally thought and either create a proper exception for it and document this behaviour. But that's, again, on a per-method basis, not something you can apply in blanket fashion.
Your approach is fundamentally at odds with the need for the compiler to see that the flow terminates at the throw statement.
I'd suggest having a utility method that just constructs an exception, which you then throw from the original point.
It's either than or put dummy returns after each call to quickRaise().

Trying to handle an exception two time in Java

I am trying to handle an exception 2 times
The first is in the core of a defined method :
Class Class1 {
public int method (int a, String b) {
try {
System.out.println(a+" "+b.length());
}
catch (NullPointerException e) {
// TODO: handle exception
System.out.println("catch from the method");
}
finally {
System.out.println("finally from the method");
}
return 0;
}
}
and the second
is when I call this method in main and passing a null parameter to it :
public Class Class2 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Class1 c = null;
try {
c = new Class1();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
c.method(1, null);
}
catch (Exception e) {
// TODO: handle exception
System.out.println("catch from the main");
}
finally {
System.out.println("finally from the main");
}
System.out.println("\nEnd of the main");
}
}
and the result is :
catch from the method
finally from the method
finally from the main
End of the main
And now my question is, why the catch block in the main was not executed?
Once you catch an Exception, it doesn't go any further, but you can throw it again. If you want your main to also see the exception you need to throw the exception again after it is caught. Try this:
public int method (int a, String b) throws NullPointerException{
try {
System.out.println(a+" "+b.length());
}
catch (NullPointerException e) {
// TODO: handle exception
System.out.println("catch from the method");
throw e;
}
finally {
System.out.println("finally from the method");
}
return 0;
}
Notice since there is a throw in the function now, you need to include it in the function definition
Edit: As stated by a couple of people, NullPointerException does not really need to be caught because it is an unchecked exception. This is because it is a subclass of RuntimeException.
You find many texts on the mechanics of throwing and catching exceptions. What I find more important is how to make best use of the exceptions concept.
This is not exactly an answer to your question, but maybe clarifies some concepts behind the situation at hand.
Rules of Thumb
If a method fulfilled its job, it should return normally. If it failed to do so, it should throw an exception instead of the normal return. The exception coming out of your method should contain information on the problem (most of the standard exceptions already do that quite well).
In a subordinate method, you normally shouldn't use try/catch. If something goes wrong (some exception arises inside your method), then your method typically can't complete its job, it should tell its caller by means of an exception, and the easiest way is to just let the exception ripple through.
In a top-level method (e.g. main, main-menu action, button-click action), catch all exceptions, inform the user (and maybe the administrator) and continue (if possible/appropriate).
If your method gets one exception (e.g. a NullPointerException) and wants to show a different one to its caller, catch the exception, create the desired new one, using the original one as cause, and throw this new exception. Personally, I try to avoid this "exceptions translation" as much as possible.
Use finally if you have to close some resource that you obtained inside the body, that would stay blocked for extended periods of time if not closed. Think of I/O streams, database connections/transactions and similar things. Don't do it just for memory allocation, that's the garbage collector's job.
If you follow these rules, you'll find that your code can concentrate on its main job, isn't cluttered with lots of error handling, and still is robust in case of exceptions.
Your Example
It all depends on the question "What's the job of Class1.method()?".
That might be "Print these two numbers". Then, when it gets the NullPointerException, it won't fulfill its job, so it shouldn't return normally, and instead exit with an exception, most easily by doing nothing (no try/catch at all) and just letting the exceptions framework do its automatic job. That will mean that its caller gets the original NullPointerException:
public int method (int a, String b) {
System.out.println(a+" "+b.length());
}
If the job of Class1.method() were "Print these two numbers, but only if there is a string", then you should catch the NullPointerException inside (or better, check with an if) and return normally ("I've done my job!"). Then Class2.main() should be satisfied with the non-printing in case of null, and have no reason to do any error handling after calling Class1.method(). If Class2.main() doesn't want that behaviour, it shouldn't call Class1.method() in that case.

Try - catch return method

Is this syntax best method?
method 1:
input
method2():
method2: (input)
try
catch
return(method1())
method3: (input)
....
This is so when an exception is thrown you rarely want the program to crash, so it's best to have a return statement so the user can declare a new input for the variable. I am reading my textbook for class and they don't cover a return. Otherwise, without the return, having a try-catch seems pointless if the program just terminates.
Your syntax is simply vulnerable bacaues it can easily go stackoverflow by a malicious user's repeated inputs that cause the exception in method2.
How about this:
method 1:
while
input
try
return method2(input)
catch
method2: (input)
return (some result)
method3: (input)
....
If a piece of code is in an authorative position to know exactly what to do with an exception, it can catch it and do whatever that is.
If it's not, it should throw it up to allow a higher level piece of code handle it. Sometimes it necessary to wrap such an exception in order to keep things at the same level of abstraction as the method call.
At the top level, when there is an exception no code can handle, it's up to a person to deal with it. You log the exception and apologize to the user.
The exception can be caught in the calling code.
Say you're reading a file in a method
Data readFile(String filename) {
try {
// Open file here
} catch (Exception e) {
// something has happened but you caught it here itself.
// Caller of this method may not know that.
}
}
Instead if your method throws an exception (Predefined or your custom):
Data readFile(String filename) throws FileNotFoundException {
// Open file here. If file name wrong, it throws a FileNotFoundException
}
This time the calling code knows that the method may throw an exception and thus, handle it the way it wants.
for e.g.
Data data = null;
while(data == null) {
try {
String f = /*Some code to read a string from input*/;
data = readFile(f);
} catch(Exception e) {
System.out.println("Unable to read. " + e);
}
}
Ofcourse, there are other ways to do it.

What is the best way to force a try block to break in between?

I have a try-catch block that I wish to break like a switch block but I couldn't find a recommended way of doing it. I'm fetching a lot of data in the try-catch block and wish to stop the fetching in between in case a certain condition is met. Just to get it working for now, I've deliberately forced the code to go into the catch block:
int i=0;
try {
//--do stuff----
if(//-------is condition met?--------//)
i = 1/0; // divide 1 by 0 -- a definite exception
}
catch (Exception e) {//---------do nothing---------//}
Is it safe to do this or should I go for another way?
EDIT:I'm fetching some xml data(actually, a lot). Depending on the internet connection, I need to stop the parsing after sometime(time-out) rather than go through the entire stream. I go through loops but I also make some calculations later. It doesn't make any sense to calculate with incomplete data, so I would prefer to just skip the whole thing.
This code smells of some anti-pattern but without more context we can't prescribe a better design. In general, you should only throw an exception for a truly exceptional condition in the state of your program. You should especially not throw an exception for normal (expected) control flow, instead you should use control flow statements such as loops (using break/continue) and return.
If you do wish to keep this structure (even though you should not) then I suggest explicitly throwing a special exception class to make it clear what you are doing, e.g.:
public static class ConditionMetException extends Exception { }
// ...
try {
// do stuff
if ( /* Is condition met? */ ) {
throw new ConditionMetException();
}
} catch (ConditionMetException cme) { /* Do nothing. */ }
But again, you're likely better off refactoring to use a loop and the built in break command.
Either break or throw will do what you want (and the throw would be preferable, you at least have some traceability as to WTH you're doing.
[edit]
what: try {
System.out.println ("before break");
break what;
} catch (Exception e) {}
}
[/edit]
Throwing an Exception just to break is bad practice.
Would this work for your situation?
Put the code currently inside the try into another method, fetchLotsOfData(). It can still throw IOException or whatever is appropriate.
When you want to stop doing your thing fetching the data, just return. Perhaps returning some true/false or status for the success.
So your final code is something like
int recordsRead = -1; // -1 means failure
try {
recordsRead = fetchLotsOfData();
}
catch (IOException ioe) {
// handle the exception
}
// process what you got...
I'm going to answer the "is is a good idea?" part of the question: No.
It is not a good idea to use exceptions to implement expected flow-of-control. It is possible, but not expected, just as it's possible to make all your variables Strings and implement all your data structures in arrays.
Try-blocks are for creating a scope boundary that has certain guarantees at termination (the catch and finally behavior). A code maintainer seeing:
try{ ... }catch(Exception x){}
would very strongly tend to either rethrow x (perhaps wrapped) or eliminate the block entirely.
Try-blocks are not about what's inside their scope. That's what standard looping constructs and, better, functions are for. Your question simply goes away if you put your scope in a function:
RetVal doStuff(Arg arg){
//--do stuff----
if(//-------is condition met?--------//)
return myResult;
}
It is not the try-catch that you should worry about breaking out of. From what I can tell, you are looking to do something along the lines of:
try
{
// do thing 1
// do thing 2
if (!done)
{
// do thing 3
// do thing 4
if (still not done)
{
// do thing 5
}
}
} catch (Exception e)
{
}
If that is what you are trying to do, then that is probably how you should do it (instead of trying to escape from the try-catch). The other way is to shrink your try-catch blocks to surround each task individually.
If you provide more context to your question then it may be possible to provide a better answer.
Just put the rest of the fetching into an if block with the inverse condition:
//--do stuff----
if (!shouldStop) {
// continue doing stuff
}
Looking by your code
int i=0;
try {
//--do stuff----
if(//-------is condition met?--------//)
i = 1/0; // divide 1 by 0 -- a definite exception
}
catch (Exception e) {//---------do nothing---------//}
if the condition is not met? then you dont need to worry about using break, and
if the condition is met, there will be definitely an exception, and it is handled in catch(although you are not doing anything)
If there is no other way you can use a block label
load:{
if(test)//skip the remaining load block
break load;
}
Otherwise you could refactor the loading code into a different method and return early.
Do not use exceptions for non-exception error handling. This is likely a named anti-pattern. If so, I don't know the name.
Here is an example of breaking out of a loop when an exception is thrown and not using exception handling to perform non-exception error handling:
try
{
while (... whatever ...)
{
... do something that might throw a BlammoException.
}
}
catch (BlammoException exception)
{
... handle the exception.
}
Just throw whichever exception you want caught...
boolean stopLoop = false;
while (!stopLoop) {
try {
int key = Integer.parseInt(userInput);
if (key > cutOff) throw new NumberFormatException();//<--like this
else {
System.out.println("Good job, your number didn't suck");
//do some stuff...
stopLoop = true;//<--End loop after some stuff
//some more stuff, or..
if(nomorestuff)break;//<--exit loop
}
catch (NumberFormatException nfe){
System.err.println("Enter a number less than "+cutOff);
}
}//end while

Strange problem with return in catch block in Java

I've got a strange problem with a try/catch block I'm using. I've got this method, which just gets some data from a remote service and stores it.
public WFSGetCapabilitiesResponse wfsGetCapabilities(String url) {
WFSGetCapabilitiesResponse response = new WFSGetCapabilitiesResponse();
try {
WFSDataStore data = loadWFSCapabilities(url);
String[] typeNames = data.getTypeNames();
ArrayList<WFSFeatureTypeBase> wfsLayers = new ArrayList<WFSFeatureTypeBase>();
for (int i = 0; i < typeNames.length; i++) {
String typeName = typeNames[i];
WFSFeatureTypeBase newLayer = new WFSFeatureTypeBase();
newLayer.setTypeName(typeName);
newLayer.setName(typeName.split(":")[1]);
newLayer.setTitle(data.getFeatureTypeTitle(typeName));
newLayer.setAbstract(data.getFeatureTypeAbstract(typeName));
newLayer.setServiceUrl(url.split("\\?")[0]);
wfsLayers.add(newLayer);
}
response.setWFSLayers(wfsLayers);
} catch (IOException e) {
response.setError(WCSCapabilitiesResponse.IO_EXCEPTION);
response.setErrorMessage(e.getMessage());
response.setSuccessful(false);
e.printStackTrace();
return response;
}
return response;
}
If I run with this code, I get a null pointer exception ('data' is null, but don't really know if it's relevant). However, if I remove the return statement from my catch block everything is fine.
The strange thing is, the IOException is not being caught in either case, so I can't see why it's having such an impact.
So again, with the return in the catch block it doesn't work, without it it does... I really can't see why this would happen.
Any ideas?
Well, my first thought is that the catch block can only make a difference if an IOException is thrown - so we know for sure that that's happening. And likewise we know that without the catch block, this exception will propagate out of the wfsGetCapabilities method (presumably you added an appropriate throws declaration when you removed the catch block).
So chances are, in the "working" case, the calling code is catching the IOException higher up and handling it in such a way that your method appears to work judging by the output. Of course your method didn't work, and threw an exception, but perhaps there's a default fallback (or similar) which is invoked in an error case?
So that's the "strange" part hopefully dealt with. As for the "problem" part, if you're getting a NullPointerException thrown with the catch block, but not without it, it's clear that your catch block logic is not quite right and is causing this problem. From what you've posted it doesn't look like any of those immediate references would be null - take a look at the stack trace and determine from which line the exception is thrown, then fix it as you would any other NPE.

Categories

Resources