Java - Can I use an empty catch statement? - java

I am working on a basic Java command line email client application. The connector I was provided with will send me emails, however if I "send" an email it will not be located on the connector as I created this email myself. Now when I want to delete an email I can find the folder I am in and delete it by its ID. I also want to delete it from the connector if its located inside the connector so that I will not receive this email again when I refresh emails.
public boolean delete(int messageId) throws IndexOutOfBoundsException
{
if (folders.get(getActiveFolderName()).delete(messageId))
{
if (connector.retrMessage(messageId) != null)
{
connector.markMessageForDeleting(messageId);
//throws exception if not found on connector
}
return true;
}
return false;
}
I tried this, is this a really bad way of going about handling exceptions?:
public boolean delete(int messageId)
{
if (folders.get(getActiveFolderName()).delete(messageId))
{
try{
connector.markMessageForDeleting(messageId);
} catch (IndexOutOfBoundsException e)
{
//this successfully soaks up the exception if its not located in connector
}
return true;
}
return false;
}
Thanks

Though they are considered as bad, as long as you are aware of what's going on and took necessary steps to recover from abnormal behaviour of the program, it will be fine.
I'm just suggesting to you to put at least a log statement.

I would personally not think so. You are using the exception as an indicator of a particular result. You're not trying to hide some error in the code by not doing anything when you catch it. However, I'm not sure if you have the ability to change anything about this connector, but if so, you should adjust it so it isn't throwing errors like that in the first place.

What you're doing is called exception swallowing. It's generally considered bad practice. The risk is to swallow exceptions that might happen when your emails are located in the connector. You don't want that.
You already know a reason to have an IndexOutOfBoundsException, so why not test first if your email is located in the connector?

It is always good practice to log any exception & then can be ignored in the cases like yours.
P.S.: No need to flood the log with stack trace in your case. It can be a simple error message indicating that the exception can be ignored safely.

Related

Why does squid:S1166 not accept exception messages only when logging caught exceptions?

Quote from the description of the rule (SonarQube 4.5.5):
// Noncompliant - exception is lost (only message is preserved)
try { /* ... */ }
catch (Exception e) { LOGGER.info(e.getMessage()); }
By providing the exception class to the logger a stack trace is written to the logs.
The problem in our code base is this:
By following the Tell, don't ask principle, we use checked exceptions as part of the, what we consider, normal execution paths and we don't want them to result in unreasonably large log messages.
A few examples: Servers responding with error codes, database statement executions failing on optimistic locking (concurrent users)...
My suggestion: Split this case in two.
// Noncompliant - exception is lost (only message is preserved)
try { /* ... */ }
catch (Exception e) { LOGGER.info(e.getMessage()); }
and
// Compliant - exception is lost (only message is preserved) but there is business logic handling the situation
try {
/* ... */
} catch (Exception e) {
LOGGER.info(e.getMessage());
*/ exception handling */
}
The rule squid:S00108 (code blocks must not be empty) would not catch the problem since there is a logging statement.
Is this not reasonable? Have I missed something of importance?
Note: I've rewritten the question to clarify my use case
I understand the arguments for maintaining the stack trace and all that, but I think it's going to bloat your logs for a < ERROR level event. One solution is to log the message as a WARN and log the exception object as DEBUG or TRACE. That way a normal user log config would not be flooded with business as usual stack traces, but it would still be possible to get a stack trace if necessary.
If it's causing hundreds of what you consider to be FP's then you should think about turning the rule off, or excluding it from your project files.
But to answer your question:
The point of exception logging is to leave enough information for investigators to figure out the cause of a problem.
If your messages are detailed, e.g.
The x in the y method broke because the frabjous was not day enough
then perhaps they fulfill that purpose. But what about a message like
Something went wrong
?
Further, you know exactly what each exception message means, but someday you'll presumably move on to bigger and better things. Will the next guy who supports the system have the same depth of knowledge? He may be grateful for the stacktraces and line numbers that tell him where to start looking...
But finally, I have to ask: why are you getting and logging so many exceptions that you flood the logger?
(Adding another answer to address the question as rewritten:)
Why would you both handle the exception and log it? If it's handled, there's no reason to log.
try to pass whole object to method than just a e.getMessage()LOGGER.info("INFO "e.);

Handling different exceptions of the same type in Java?

When handling errors in Java it's common to see the superclasses being the errors that are caugh, such as
Exception, IOException, SocketException, etc.
However how do you go about finding the nitty-gritty details on the exception? How do you single a certain exception type out from the others. For instance, I'm currently working on a small project using Netty.io which throws an IOException for every type of read/write error you can name. This makes sense, because ultimately this is input/output errors, but how would I handle them individually.
Example exceptions:
java.io.IOException: An existing connection was forcibly closed by the remote host
java.io.IOException: Connection reset by peer
java.io.IOException: Stream closed
The list just continues to go on, but how would you go about handling these seperately, one approach that I've found while looking around and seems really nasty is the following.
try {
// ...
} catch (IOException e) {
if(e.getMessage().contains("An existing connection was forcibly closed by the remote host")) {
// Handle error
} else //...
}
This seems very tedious and there's bound to be a better way to do this, a correct way if you will. I've looked through quite a bit of error handling writeups over the last few hours and they all only talk about the big boys that are used commonly. IOException, Exception, SocketException, NullPointerException, and FileNotFoundException. Where I believe SocketException and FileNotFoundException would be directly related to the IOException, more than likely a subclass, correct me if I'm wrong.
Anyway, what's the proper way to go about handling these exceptions and how do you figure out exactly what kind of exception you need to be handling? All I can really do is handle IOException until something more precise comes up, but when developing applications it's always good to be able to handle each error uniquely.
In most of these cases the message is irrelevant from the point of view of your code. It's just something to be shown to the user, or logged. The only salient fact is that the connection is broken, for whatever reason, and there aren't different code paths you can use depending on which message it was.
The only one that's different is 'socket closed', which indicates a coding bug.
EDIT Regarding your comments below:
Any IOException other than SocketTimeoutException on a socket is fatal to the connection.
Invalid packets don't cause IOException: that's an application-layer problem that throws application-layer exceptions, or subclasses of IOException: e.g., java.io.StreamCorruptedException.
There is no such thing as IOException: connection closed by remote host. If the peer closes the connection, that causes an end-of-stream condition, which manifests itself as either read() returning -1, readLine() returning null, or readXXX() throwing EOFException for any other X.
I would suggest catching the exceptions in order, from most specific to least - such that you will notice a circuit break pattern when the exception you are looking for is reached. This is the best I can come up with:
try {
/// Something that can result in IOException or a SocketException
catch (IOException e){
//Do something specific
}catch (SocketExcpetion e){
}catch (Exception e) { //or some superclass of the above exceptions
///
}
Don't forget that you can also catch multiple exceptions of different types using the | command: catch (IOException|SocketException|
The documentation (http://docs.oracle.com/javase/7/docs/api/java/io/IOException.html) contains a long list of direct subclasses. You might want to look through them and check which ones you want to treat differently.
Once you know that, you can use multiple catch-blocks, first the subclasses, then the most general IOException:
catch(SSLException se) {
// do something
}
catch(HttpRetryException he) {
// do something else
}
catch(IOException ioe) {
// nop
}

Adding exception to existing method

I have a simple database connection method that I want to add a condition that if the connection fails then an email is sent to a list of people telling that it failed to connect.
My current method is this:
public Connection createInitialConnection() throws ClassNotFoundException, SQLException, PollingException
{
DBConnectionDetails conDetails = new DBConnectionDetails("INITIAL");
Class.forName(conDetails.getDriver());
Connection connInitial = DriverManager.getConnection(conDetails.getUrl(),
conDetails.getUser(), conDetails.getPassword());
logger.info("Initial connection created" + conDetails.getUrl());
return connInitial;
}
Currently, there is no checking to see if the connection was successful, if it does not connect then the program just keeps going.
I'm not sure about the best way to do this would be. An if/else or try/catch?
Logging libraries like log4j allow you to add a logging appender that sends emails for each log entry (of course you can filter by severity, category, etc.). So when you attempt to get a connection and an exception is thrown it should get caught by the exception handler and logged, and the logger will send emails.
That assumes your application has some kind of exception handler that logs uncaught exceptions. Where that happens depends on your application's architecture. It could be in a servlet, in try-catch code in the jsp, or in a dedicated handler in a webapp framework like struts or spring-mvc.
If you implement this you will have a way to be notified when any exceptions are getting logged, it won't be limited to database connectivity problems.
You can send email on catch block.
try{
Class.forName(conDetails.getDriver());
Connection connInitial = DriverManager.getConnection(conDetails.getUrl(),
conDetails.getUser(), conDetails.getPassword());
}
catch(SQLException | ClassNotFoundException ex){ // Java 7 needed for multicatch
// Send the Email.
}
Maybe you should try to catch SQLExcepton and then, send notification like this :
try {
Connection connInitial = DriverManager.getConnection(conDetails.getUrl(), conDetails.getUser(), conDetails.getPassword());
} catch (SQLException e) {
//send notification here
}
catch block. It is always better than if-else
try{
// your Logic to test the connection
}
catch(Exception ex)
{
//Code to send the mail if the connection is failed.
}
You can do with try { } Catch .. This in case you have an execption like no network or somthing. after that you need to check if Connection != null.. This is all you need
Sending an email in the catch block might be OK for your application, but then you're faced with how to configure the email. Who should receive it? Are multiple recipients possible? How should the senders, subject and format be configured and passed to your mailer? What if the mailer fails? You may find yourself reinventing an existing solution if you go that route.
If you're using Log4j, it might be a good idea to configure a SMTPAppender for your existing logger or create a logger for errors which need to be sent over email. You can configure Log4j to use the appender for only SQL exceptions if you like (ie. log4j: Log output of a specific class to a specific appender).

Does throwing any exception cause the GAE instance to restart

In my code i have a lot of code like the following. I am wondering if it's a bad thing for my server and if it will cause the instance to restart.
if (opLoginId == loginId) {
datastore.delete(key);
return 0;
} else {
throw new WebApplicationException(Response.Status.UNAUTHORIZED);
}
Unless these are being caught at some higher level (say, to turn them into the right HTTP response), then yes, you're killing your instance.

Is it possible to read an answer before an exception?

I'm working on a project where an android application is communicating with a PHP server (WAMP) where some methods are implemented. We're using XMLRPC to handle client calls to server's methods. Anyway, even though everything happens fine, an exception is thrown when java tries to read the answer. So I would like to know if there is any way to read or save the server's response before java throws the exception (which is not really relevant) ?
Thanks in advance for your help !
The usual approach is to catch and handle this unchecked exception in your code. If you don't catch it, it will cause the application to stop.
Wrap the piece of code that causes the exception into a try/catch statement. This should allow you application to continue and you should be able to keep and process the response.
I do already set up a try/catch statement as you can see :
Integer result2 = null;
try {
Object[] dataParams = new Object[]{bytes, date, login};
result2 = ((Integer) client.execute("storeData", dataParams)).intValue();
System.out.println(result2.toString());
} catch (Exception ex)
{
ex.printStackTrace();
}
The storeData method is supposed to return an int. But as I get an exception, I can't see that response.
This is the error I get : [Fatal Error] :1:1: Content is not allowed in prolog.
I assume it's due to some bad characters in the xml response so that's why I'd like to get this response !

Categories

Resources