try-with-resources and catching Exceptions which are both thrown during normal execution and autoClose - exception

I am pondering for a while with the following code:
try (Connection conn = dbHandler.getConnection()) {
// do something with the connection
dbConn.commit();
} catch (SQLException e) {
System.err.println("Too bad!");
e.printStackTrace();
}
Consider my application needs to be resilient to some SQL locking/dead-lock situations, so I would need to do some specific handling inside of the catch block. However, I cannot easily identify, if the exception was thrown during the "do something" part of my code or during autoClose(). And of course, each JDBC driver throws slightly different exceptions and if you throw JDBI in the mix, it gets even more complicated. So you can't really rely on different catch clauses do precisely identify, when the exception got thrown.
The only solution I could come up with is this code:
boolean finishedProcessing = false;
try (Connection conn = dbHandler.getConnection()) {
// do something with the connection
dbConn.commit();
finishedProcessing = true;
} catch (SQLException e) {
if (finishedProcessing) {
// this is an exception during autoClose
System.err.println("Too bad!");
e.printStackTrace();
} else {
// handle rollback cases, retries etc
System.err.println("SQL recovery performed.");
throw e;
}
}
Now the same issue comes up with IOExceptions for File* operations and probably in many other cases.
To be honest, I am just hoping I missed something completely obvious and I appreciate any insight from the Java experts out here.
As stated above, the only solution I found so far is introducing state-variables into the code, which doesn't really make sense to me.
I am fully aware of suppressing exceptions from the autoClose process, when an exception got thrown by the try block, however, as stated above the same kind of exception can be thrown, suppressed and both.

Don't use try-with-resources and add a finally block.
Connection conn = null;
try {
conn = dbHandler.getConnection()
// do something with the connection
dbConn.commit();
}
catch (SQLException e) {
// Handle rollback cases, retries, etc.
System.err.println("SQL recovery performed.");
e.printStackTrace();
}
finally {
if (conn != null) {
try {
conn.close();
}
catch (SQLException xSql) {
System.out.println("Failed to close database connection.");
xSql.printStackTrace();
}
}
}

Related

Confusion about "eating an exception" (in Java)?

What exactly is eating an exception?
Is it when there's nothing in the catch block or when you don't log the exception?
I understand that this is eating an exception.
try {
//exception code
} catch (Exception e) {
}
However, what about this?
try {
//exception code
} catch (Exception e) {
System.out.println("Exception Thrown");
}
When there is nothing in the catch block.
In general it is necessary to catch the more specific exception if it is possible to recover that exception and if not log the exception and rethrown it.
A program that "eat" exception is a bad practice because could be in an inconsistent state.

How to throw SystemException in java?

I saw many people wrote like:
try {
//something
}
catch (IOException e){
throw new SystemException("IO Error", e);
}
I got "Cannot instantiate the type SystemException" error and it seems SystemException is a abstract class, how can I able to throw it?
Yes, it is an abstract class and that means that it does not make sense to construct an object of type SystemException. It is recommended to use more meaningful exceptions types.
You have mentioned IOException in your code. This means an exception related to an I/O operation and the catcher can act accordingly (maybe a special log level, some I/O cleanup etc.).
In your particular case, I think you should change it to:
try {
//something
}
catch (IOException e) {
// log exception info and other context information here
// e.g. e.printStackTrace();
// just rethrowing the exception (call stack is still there)
throw e;
}
P.S. Quite offtopic, but coming from .NET world I have found about the subtle difference between throw ex; in C# vs. Java.

Combining Multiple Exceptions in Custom Exception : Optimization

I have few similar methods and there calls as follows :
methodThrowingException() throws NullPointerException, InterruptedException, TimeoutException {
<method logic>
}
Calling class :
try{
methodThrowingExceptions();
<some other logic>
}
catch (NullPointerException npx) {
npx.printStackTrace();
log more details...
}
catch (InterruptedException inx) {
inx.printStackTrace();
log more details...
}
catch (TimeoutException tox) {
tox.printStackTrace();
log more details..
}
How (if) can I put all of these three in one Custom Exception?
Other than (1) is there a way to optimise the code so that I need not write the entire same statements for multiple methods?
Since Java 7, you can use a multi-catch block:
catch (NullPointerException | InterruptedException | TimeoutException e) {
e.printStackTrace();
log more details...
}
That said, you should never catch NullPointerException: that is a bug, and if it happens, the exception should bubble up. You can't reasonably expect a NPE to happen.
In addition, doing the same thing for an InterruptedException as for the other exceptions is also very dubious. When catching an InterruptedException, you should reset the interrupted flag on the current thread, and stop what you're doing ASAP.

calling ExecuteReader() from catch block

I have the following code and when exception happens the ExecuteReader() in Catch block will hang the app.
My question is why the hang? I can't perform query inside of Catch block if query exception happens in general?
Try {
// some SQL queries
}
catch (SqlException odbcEx) {
// do some queries with IDbCommand::ExecuteReader()
}
catch (Exception ex) {
// Handle generic ones here.
}
Thanks,
The ExecuteReader() keeps hold of your SQL connection. What you want to do is wrap a using statement round it. Also, you can't perform a SQL query because you have essentially errored and lost scope of your SQL connection variable. If you want, you can do some further SQL in the exception block by instantiating a new instance of your reader and connection, however ideally close of your existing connection before doing so. If you use a datatable you won't keep hold of the SQL connection. Perhaps something to look at.
For example:
using (var conn = new SqlConnection("ConnectionString"))
{
try {
// some SQL queries
}
catch (SqlException odbcEx) {
// do some queries with IDbCommand::ExecuteReader()
}
catch (Exception ex) {
// Handle generic ones here.
}
finally {
conn.Close();
}
}
This way you are disposing of your connection and not keeping hold of it.

Check APEX exception type

I'm looking to check what type of exception is retruned in the following code snippet.
I'm not sure exactly how to do it though, or if it's even possible.
try {
//SOME LOGIC
} catch (exception ex) {
System.debug(//EXCEPTION TYPE);
}
Would anyone have any suggestions or advice??
try {
//SOME LOGIC
} catch (Exception ex) {
System.err.println(ex.getClass().getName());
}
Few things:
You have posted exception. I assume you meant Exception.
System.debug does not exist.
I have answered your specific question but obviously this is not standard exception handling code. You will instead output the stacktrace, log the exception or rethrow a different one.
Firstly, within your catch block(s), specify the exception. Semantically, types including Exception are not in camel case.
Secondly, you can obtain the exception type through Exception.getClass().getName():
catch (Exception exception) {
System.out.println(exception.getClass().getName());
// exception.printStackTrace();
// throw exception;
}
Specified by:http://docs.oracle.com/javase/7/docs/api/java/lang/Exception.html
After some searching around I found an answer,
try {
//SOME LOGIC
} catch (Exception ex) {
System.debug(ex.getTypeName());
}
The getTypeName() method does the trick nicely.
I apologise for not specifying I was working in Apex in my question.