I have a piece of code that has driven me nuts.
The general flow is that when a certain event in TRY occurs, I throw the exception... according to my understanding, whenever the throw is called, it simply stops further execution in the same class and return the control back from where this class's function was called...
Here is the code...
try{
session = getHibernateSession();
companyAccountLinkingWSBean = (CompanyAccountLinkingWSBean) wsAttribute
.getBeanObject();
companyToMatch = companyAccountLinkingWSBean.getCompanyCode();
cnicToMatch = companyAccountLinkingWSBean.getCnic();
LOG.debug("We have found the Mobile number from the WS Bean as input");
mobile = companyAccountLinkingWSBean.getMobileNumber();
LOG.info("Mobile is : " + mobile);
if(mobile.isEmpty()){
LOG.info("Coming in mobile.isEmpty()");
companyResponceWSBean = new CompanyResponceWSBean();
companyResponceWSBean.setpID(Constants.INPUT_MOBILE_ERROR);
companyResponceWSBean.setMessage(Constants.INPUT_MOBILE_ERROR_MSG);
companyResponceWSBean.setSuccess(false);
response = new WSAttribute();
response.setBeanObject(companyResponceWSBean);
LOG.info("BEFORE THROWING");
throw new PayboxFault(Constants.INPUT_MOBILE_ERROR,
Constants.INPUT_MOBILE_ERROR_MSG);
}
LOG.info("Out side IF statement!!");
} catch (Exception e) {
LOG.info("IN Exception!!");
}
LOG.info("Out Side Exception . . . Before Returning ");
return response;
Output in LOG When Empty mobile field is given as input ...
We have found the Mobile number from the WS Bean as input
Mobile is :
Coming in mobile.isEmpty()
BEFORE THROWING
IN Exception!!
Out Side Exception . . . Before Returning
How is it actually possible?
Your understanding isn't quite correct. Catching an exception handles it, and after the catch is completed, flow will continue after the try/catch, unless you throw another exception, or re-throw the exception. This might explain it better:
try {
// Happy case flow here ...
throw new PayboxFault(...);
// If an exception is thrown, the remainder of the `try` block is skipped
} catch (Exception e) {
// The exception is now handled ...
// Unless a new exception is thrown, or the caught exception re-thrown
} finally {
// Code here should always be called after the try OR catch block executes,
// Finally is called even if the catch re-throws
}
// Code after the try-catch-finally executes if the try completes successfully
// OR if the exception is handled in the catch, but not if the catch re-throws
When you catch an exception, execution continues from after the catch block. If you don't want it to, you'll need to return from inside your catch (or not catch the exception at all and let it bubble up to the caller).
catch (Exception e)
{
LOG.info("IN Exception!!");
return null;
}
Or:
catch (Exception e)
{
...
throw e; // rethrow exception.
}
Note that if you do this, the exception will continue to bubble up the call stack until you catch it somewhere else (such as in the calling method).
You are catching the Exception. So it will not transfer back the control to the calling function unless entire function is executed.
If you want to skip the
LOG.info("Out Side Exception . . . Before Returning ");
statement you can do
catch (Exception e) {
LOG.info("IN Exception!!");
throw e;
}
And about
when ever the throw is called, it simply stops further execution in the same
class and return the control back from where this class's function was called...
Yes only if you do not catch it. You catch an Exception if you intent to do something with it which includes logging it and rethrowing.
Related
We are monitoring our application by using timers. In case of an exception, we would like to catch the exception, stop the timer with an error, and rethrow the same exception without handling it. Which of the following catch objects would be the best approach to handle it?
Catch specific exceptions - will monitor only the specific exceptions but not all of them. Considered as best practice, but we will have to think and add all the possibilities each time we use a timer.
Catch Exception - will monitor all the Exceptions but not the Errors like OOM. Considered as bad practice, but in this case, we throwing back the exception, so we won't lose any data.
Catch Throwable - will monitor bot Exception and Error. Considered as bad practice, but in this case, we throwing back the exception, so we won't lose any data and we are not handling the Error.
public void run() {
Timer timer = monitoring.timer();
try {
timer.start();
// some logic
timer.stop(aSuccessTag());
// 1. catch specific exceptions
} catch (RuntimeException | IOException e) {
timer.stop(new TagList().tags(aFailureTag(e.getClass())));
throw e;
}
// 2. catch exception
} catch (Exception e) {
timer.stop(new TagList().tags(aFailureTag(e.getClass())));
throw e;
}
// 3. catch error and exception
catch (Throwable e) {
timer.stop(new TagList().tags(aFailureTag(e.getClass())));
throw e;
}
}
Thanks
Elad
I am using SonarQube for code quality. I got one issue related to exception handling, which says remove throw clause from finally block.
} catch(Exception e) {
throw new MyException("request failed : ", e);
} finally {
try {
httpClient.close();
} catch (IOException e) {
throw new MyException("failed to close server conn: ", e);
}
}
Based on my understanding above code looks good. If I remove throw clause and suppress exception in finally then caller of this method will not be able to know server's status. I am not sure how we can achieve same functionality without having throw clause.
Your best shot is to use the Automatic Resource Management feature of Java, available since Java 7. If that is for some reason not available to you, then the next best thing is to replicate what that syntactic sugar expands into:
public static void runWithoutMasking() throws MyException {
AutoClose autoClose = new AutoClose();
MyException myException = null;
try {
autoClose.work();
} catch (MyException e) {
myException = e;
throw e;
} finally {
if (myException != null) {
try {
autoClose.close();
} catch (Throwable t) {
myException.addSuppressed(t);
}
} else {
autoClose.close();
}
}
}
Things to note:
your code swallows the original exception from the try block in case closing the resource fails. The original exception is surely more important for diagnostic;
in the ARM idiom above, closing the resource is done differently depending on whether there already was an exception in the try-block. If try completed normally, then the resource is closed outside any try-catch block, naturally propagating any exception.
Generally, methods in the finally block are 'cleanup' codes (Closing the Connection, etc) which the user does not necessarily need to know.
What I do for these exceptions is to absorb the exception, but log the details.
finally{
try{
connection.close();
}catch(SQLException e){
// do nothing and just log the error
LOG.error("Something happened while closing connection. Cause: " + e.getMessage());
}
}
You're getting a warning because this code could potentially throw an exception while dealing with a thrown exception. You can use the try with resource syntax to close the resource automatically. Read more here.
In the case that the "request failed : " exception is thrown and you fail to close the httpclient, the second exception is the one that would bubble up.
I am not sure how we can achieve same functionality without having
throw clause.
You could nest the two try blocks differently to achieve the same result:
HttpClient httpClient = null; // initialize
try {
try {
// do something with httpClient
} catch(Exception e) {
throw new MyException("request failed : ", e);
} finally {
httpClient.close();
}
} catch (IOException e) {
throw new MyException("failed to close server conn: ", e);
}
First of all: StackOverflow tells me that the question is subjective, which it is not.
I have this code:
try {
// Some I/O code that should work fine, but might go weird
// when the programmer fails or other stuff happens...
// It will also throw exceptions that are completely fine,
// such as when the socket is closed and we try to read, etc.
} catch (Exception ex) {
String msg = ex.getMessage();
if (msg != null) {
msg = msg.toLowerCase();
}
if (msg == null || (!msg.equals("pipe closed") &&
!msg.equals("end of stream reached") &&
!msg.equals("stream closed") &&
!msg.equals("connection reset") &&
!msg.equals("socket closed"))) {
// only handle (log etc) exceptions that we did not expect
onUnusualException(ex);
}
throw ex;
}
As you can see my procedure of checking for certain exceptions works, but is VERY dirty. I'm afraid that some VMs might use other strings for the exceptions that should NOT cause the specified method to be called.
What are different solutions I could use for this problem? If I use IOException to check for non-unusual (lol) exceptions, I will not catch any unusual exceptions that derive from it or use it.
For an exception that extends IOException (or another exception), put it in a separate catch statement before the Exception that it extends.
try {
// this might throw exceptions
} catch (FileNotFoundException e) { // this extends IOException
// code
} catch (IOException e) {
// more code
}
In the above example, the code in the first statement will be executed if the exception is an instance of FileNotFoundException. The second one will be executed only if it is an IOException that is not a FileNotFoundException. Using this approach, you can deal with multiple exception types that extend each other.
You can also catch multiple types of exceptions in the same catch statement.
try {
// even more code
} catch (IOException|ArithmeticException e) {
// this will run if an IOException or ArithmeticException is thrown
}
Hope this helps.
In the following code snippet, if ex1 is thrown, will be be caught by the second catch block, or will it be thrown back to the caller of the method?
And if it is thrown back to the caller, and then a second exception occurs in the finally block (ex2), does that mean 2 exceptions will be thrown back to the caller (ex1 and ex2)?
try {
// write to file
} catch (IOException ex1) {
throw ex1;
} finally {
try {
aBufferedWriter.close();
} catch (IOException ex2) {
throw ex2;
}
}
Both of those exceptions would be thrown back to the caller... although a single exception in any particular situation. If the body of the outer try block throws and then close throws as well, only the second exception would be seen by the caller.
However, having a catch block just to rethrow is pointless. Your code would be clearer as:
try {
// write to file
} finally {
aBufferedWriter.close();
}
In Java 7, a try-with-resources statement can do that automatically:
try (BufferedWriter writer = new BufferedWriter(...)) {
// Use the writer here
} // The writer is auto-closed here
That way you can also get at an exception on close separately from an exception in the main body, using Throwable.getSuppressed.
Depends on the design. You can also try
try{
try{
//write to file
}finally{
aBufferedWriter.close();
}
}catch(IOException e){
}
Also why catch the exception if you want to throw it.
Q. In the following code snippet, if ex1 is thrown, will be be caught by the second catch block, or will it be thrown back to the caller of the method?
No, it won't be caught by the catch block inside the finally, provided there is no exception in the finally block and thus the exception ex1 would be thrown back to the caller method.
Q. And if it is thrown back to the caller, and then a second exception occurs in the finally block (ex2), does that mean 2 exceptions will be thrown back to the caller (ex1 and ex2)?
In this case, since a exception gets thrown in the finally block, it'll overwrite the exception thrown in the outer catch block and resulting in the exception ex2 getting thrown back to the caller method.
Only either of the exceptions would be thrown back to the caller method for a single execution of this, not both. That being said, having a catch block just to throw back the exception which has been caught, is really pointless.
Before Java 7, the really accurate pattern was
public void writeToFile(String file) throws IOException {
IOException exception = null;
OutputStream out = new FileOutputStream(file);
try {
// TODO: write data to file
} catch (IOException ex) {
// store exception for later rethrow
exception = ex;
} finally {
try {
out.close();
} catch (IOException ex) {
// do NOT supress 'outer' exception:
if (exception == null) {
exception = ex;
}
}
}
if (exception != null) {
throw exception;
}
}
Looks crazy, but this covers every possibility and circumvents exception supressed exceptions (when an exception is thrown in the finally statement, it supresses the 'real' exception that happened in the try block - if any).
But maybe - for the sake of readability - you can live with suppressed exceptions and do it like that:
OutputStream out = new FileOutputStream(file);
try {
// TODO: write data to file
} finally {
out.close(); // if an exception is thrown here, it hides the original exception
}
See also http://tutorials.jenkov.com/java-exception-handling/exception-handling-templates.html
Since Java 7, you can do (almost) the same with a try-with-resource statement:
public void writeToFile(String file) throws IOException {
try (OutputStream out = new FileOutputStream(file)) {
// TODO: write data to file
}
}
Note that exceptions that are thrown when the resource is closed do NOT suppress the original exception. Instead this additional exceptions are added as 'suppressed exceptions' to the base exception. You can get them with baseException.getSuppressed() (Java 7 and above!).
See also http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
I have a method that looks like this:
try {
doStuff();
} catch (Exception ex) {
logger.error(ex);
}
(I don't really use method names like doStuff - this is just to make things easy)
In doStuff I do a variety of things, among them is call a data access method (so, another method within doStuff) that ends with the following:
} catch (SQLException ex) {
logger.error(ex);
} finally {
try {
connection.close();
proc.close();
results.close();
} catch (Exception e) {
logger.error(e);
} //<--Exception thrown here. HUH?
}
return stuff;
When stepping through this code I get to the second to last curly brace (marked with a comment) and then jump up to the catch in the first code block with a NullPointer exception. The results.close() is what is being run right before it (results is not null). My IDE (NetBeans) doesn't provide a stack trace (it shows the stack trace is null) or any other information other than the name of the exception (from what I can tell).
This code was running fine previously. In fact while it was running, I changed the stored procedure that the data access method (where I'm getting this exception) was calling, and then this error started to occur (without the application having been stopped at all). I've since tried rebuilding and restarting but to no avail. I could change the sproc back but I really want to find out what this error is from since it makes no sense that the sproc would even be a part of this considering where in the code the exception is occurring.
your doStuff() method is throwing something other than a SQLException and it is not being caught. add a catch(Exception e) block and log that exception and see what happens.
this code sample exhibits the same behaviour you are describing:
public class TryCatchTest {
public static void main(String[] args) {
try {
System.out.println("foo");
throw new NullPointerException();
} finally {
try {
System.out.println("bar");
} catch (Exception e) {
e.printStackTrace();
}
} // exception thrown here
}
}
Close the resources in the reverse order in which they were obtained:
try
{
results.close();
proc.close();
connection.close();
}
catch (Exception e)
{
logger.error(e);
} //<--Exception thrown here. HUH?
I'd also recommend methods like these:
public class DatabaseUtils
{
// similar for ResultSet and Statement
public static void close(Connection c)
{
try
{
if (c != null)
{
c.close();
}
}
catch (SQLException e)
{
// log or print.
}
}
}
It could well be that logger is null.
Hard-to-pinpoint exceptions are often thrown in the exception handler itself.
NullPointerException can not be thrown in a line without a statement.
Check that the class file you are executing is of the same version as the source you view (I have had similar issues when an incorrectly configured classpath contained a class twice and the older version was found first in the classpath, or a recompiled class files for not correctly copied to the web container I used for testing).
Edit: As emh points out, it could also be that exception occured prior to entering the finally block.
I'm 99% sure this is happening in the JDBC driver. For starters, your close statements are backwards. You should close the resultset, the statement and the connection, in that order.
If you are running in an application server which is managing the transactions, then the attempt to commit the transaction may trigger the exception inside the JDBC driver.
It could also be something about how result sets are generated in the stored proceedure, such as accessing one, then accessing another, and then referring back to the first one.
As I said in a comment, never catch an exception that you don't want to deal with. In your code, assuming that it is complete, you are not doing anything interesting with the exception, and it is causing you confusion on where and why the exception is happening. If you really want to do more than log or printStackTrace(), like wrapping it with a domain-specific exception (like your.package.DataAccessException or something), then great.
Do something more like this:
ResultSet results = null;
CallableStatement proc = null;
Connection connection = null;
try {
connection = >
proc = connection.createCallableStatement(..);
results = proc.execute(..);
>
} finally {
try {
if ( results != null ) {
results.close();
}
} catch (Exception e) {
logger.error(e);
}
try {
if ( proc != null ) {
proc.close();
}
} catch (Exception e) {
logger.error(e);
}
try {
if ( connection != null ) {
connection.close();
}
} catch (Exception e) {
logger.error(e);
}
}
And then in the caller:
try {
doStuff();
} catch ( SQLException e ) {
throw new your.package.DataAccessException(e);
// or just let the SQLException propagate upward
} catch ( Exception e ) {
throw new your.package.AppException("omg, crazy pills!", e);
// or, once again, just let the exception
// propagate and don't catch anything
}
So, take-away:
don't log exception where they happen, just pass them on, nested in another exception. You don't want your process to not know whether or not the SQL action succeeded or not. You would rather stop and do something else.
Nest exceptions until the get to the end of the line, that way, you always have the complete trace in the place that you wanted to deal with the exception, not in five places scattered throughout your server log.
Nest exceptions (yes, I said that twice!) so that you don't care where the JVM actually throws the exception from, you have the next exception to follow, telling you it was actually a callable statement, or improper closing of your resources, etc.
Don't nest and throw exceptions from errors caught in your finally code, that will interfere with the original exception and that will be more interesting than the failure to close and statement that didn't get opened in the first place.
Set variables to null before you use them, and then check for null before close()ing them.
Catch each problem in the finally block individually, as you might not be able to close your ResultSet (because some execution error caused it not to open in the first place), but you should still try to close the CallableStatement and Connection, as it is probably unaffected and will still cause you to leak resources.
Hope that helps.