I have a code that throws a bunch of Exceptions but each of them only contains a printStackTrace() method as shown below
} catch (SecurityException e) {
// TODO Auto-generated catch block
System.err.println(e);
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Is this sufficient or do I need to include additional statements like System.err.println(e)? Usually, if an exception occurs I am able to trace the source with the above alone.
If there is something you can do to solve the problem, do it in the catch, if there is nothing you can do, then it is better to use a logging framework to register the exception than to use e.printStackTrace(); or System.err.println(e);
I personally recommend: http://www.slf4j.org/, but if you have masochistic tendencies you can try the very bad (but official) Java Logging API: http://download.oracle.com/javase/1.4.2/docs/guide/util/logging/ .
One extra advantage of SLF4J is that it can redirect its logging to the awful Java Logging API (that way you can use an elegantly designed API and still comform to the awfully designed (de jure not de facto) "standard"
SLF4J is easy to use, to log an exception all you have to do is write logger.error("some accompanying message", exception);, another of its advantages is that you can, for example, configure it to send you an email each time your application crashes (by using logback as the underlying logging engine)
It depends on the exceptions. Obviously, with printStackTrace() the exception will be printed for you to debug (or users to report to you). However there is no additional error handling.
Example:
If an IOException is thrown, you might want to show the user a error message specifying the exact error cause, or you might want to do another attempt, transparent for the user. Or you might want to abort the whole program if the operation is critical for the success of the whole task... etc.
If you want to trace the source e.printStackTrace() is enough.
Usually I put e.printStackTrace(); at DEBUG level. Also I add meaningful error message at ERROR level for the users.
I think you might be missing a bit about the basics of exceptions and exception handling.
The golden rule of exceptions is that they should be exceptional.
This is why you might have seen or read that you should never catch the base Exception - there is simply no way that your code can handle every time of exception.
So as a general rule you should only catch exceptions if you can handle them in a specific way. For example, if you're reading a user's details from a file and that fails you might choose to return a new user. What you don't want to do is simply catch the exception and log it. This leads to an application that is robust but simply swallows errors which leads to an extremely bad user experience.
If your method can't handle an exception it should simply not catch it and defer the exception handling to a higher level. This usually means an error message will be displayed to the user (at the top level).
If you can afford to use a logging framework like log4j, you'll be able to call
}catch(Exception e){ log.error("Exception occurred:",e}
making the log framework to log your custom message "Exception occurred" followed by the stack trace in your errorlog file
Related
What are IO Exceptions (java.io.IOException) and what causes them?
What methods/tools can be used to determine the cause so that you stop the exception from causing premature termination? What does this mean, and what can I do to fix this exception?
Java IOExceptions are Input/Output exceptions (I/O), and they occur whenever an input or output operation is failed or interpreted. For example, if you are trying to read in a file that does not exist, Java would throw an I/O exception.
When writing code that might throw an I/O exception, try writing the code in a try-catch block. You can read more about them here: https://docs.oracle.com/javase/tutorial/essential/exceptions/catch.html
Your catch block should look something like this:
try {
//do something
}catch(FileNotFoundException ex){
System.err.print("ERROR: File containing _______ information not found:\n");
ex.printStackTrace();
System.exit(1);
}
Here you go https://docs.oracle.com/javase/7/docs/api/java/io/IOException.html
IOException is thrown when an error occurred during an input-output operation. That can be reading/writing to a file, a stream (of any type), a network connection, connection with a queue, a database etc, pretty much anything that has to do with data transfer from your software to an external medium.
In order to fix it, you would want to see the stack trace of your exception or at least the message, to see exactly where the exception is thrown and why.
try {
methodThrowingIOException();
} catch (IOException e) {
System.out.println(e.getMessage()); //if you're using a logger, you can use that instead to print.
//e.printStackTrace(); //or print the full stack.
}
The error message that will be printed will likely show you what the issue is. If you add the error message here, I'll be able to give you more info on how to fix that specific IOException. Without that, no one can really give you a complete answer.
It is a very generic exception that a lot IO operation can cause. A best way is to read the Stack Trace. To continue the execution you can use the try-catch block to bypass the exception, but as you mention you should investigate into the cause.
To print the stack trace:
try {
// IO operation that could cause an exception
} catch (Exception ex) {
ex.printStackTrace();
}
IOException is usually a case in which the user inputs improper data into the program. This could be data types that the program can't handle or the name of a file that doesn't exist. When this happens, an exception (IOException) occurs telling the compiler that invalid input or invalid output has occurred.
Like others have said, you can use a try-catch statement to stop a premature termination.
try {
// Body of code
} catch (IOException e) {
e.printStackTrace();
}
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.);
Everyone talks about how important exception handling is. I have never had the need to handle them until recently:
try {
$pdo = new PDO($dns);
} catch (Exception $e) {
throw new Exception($e);
}
Another more general example would be:
if ($something) {
throw new Exception('Ouch! I can't do that!');
}
After a little online research, I found that many examples/solutions online simply echo them. (PDO Exception Questions - How to Catch Them) Some don't have solutions. (Catching PDOException in lower layer and re-throwing as different exception to upper layer) & (Where to catch exception in PHP MVC application?) And others, I just dont understand. (Where to catch exceptions)
Question #1: Where should I catch exceptions; in the Model or Controller of a MVCish framework?
Question #2: What should catching it do? Log it, email it, display 503?
I am a .net guy and for me best practices for catching exceptions:
Catch it as late as possible.
Write a common code to catch exception.
Catch it at controller level and log it somewhere with complete stack trace (ETW, Log file, DB etc.).
Redirect user to some good looking error page. Only controller can do this.
Is it a bad idea to use printStackTrace() in Android Exceptions like this?
} catch (Exception e) {
e.printStackTrace();
}
I believe this is what you need:
catch (Exception e) {
Log.e(TAG,Log.getStackTraceString(e));
}
Yes, it is a bad idea. You should instead use Android's built-in log class specifically designed for these purposes: http://developer.android.com/reference/android/util/Log.html
It gives you options to log debug messages, warnings, errors etc.
Logging errors with:
Log.e(TAG, "message", e) where the message can be an explanation of what was being attempted when the exception was thrown
or simply Log.e(TAG, e) if you do not wish to provide any message for context
You can then click on the log console at the bottom while running your code and easily search it using the TAG or log message type as a filter
Yes. printStackTrace() is convenient but discouraged, especially on Android where it is visible through logcat but gets logged at an unspecified level and without a proper message. Instead, the proper way to log an exception is...
Log.e(TAG, "Explanation of what was being attempted", e);
Note that the exception is used as a third parameter, not appended to the message parameter. Log handles the details for you – printing your message (which gives the context of what you were trying to do in your code) and the Exception's message, as well as its stack trace.
The question is: is useful at all print to the stack trace in an Andriod application context?
Will the standard output be visible at runtime? Will somebody care about it?
My point is that, if nobody is going to check the standard output and care to debug the error, the call to this method is dead code, and composing the stacktrace message is a worthless expense. If you need it only for debugging at development, you could set an accesible global constant, and check it at runtime:
} catch (Exception e) {
if(com.foo.MyEnvironmentConstants.isDebugging()) {
e.printStackTrace();
} //else do noting
}
I would avoid using printStackTrace(), use a logging system and its support of exceptions.
log.log(Level.SEVERE, "Uncaught exception", e);
So if you want to change how logging is handled it's much easier.
I have written a java class where if a method throws an exception, an email is sent, via java mail, with a report to the administrators.
It works - my question is w.r.t elegance - to catch the exception thrown by the main method, the sendEmail() method resides in the catch block of the main method. The sendEmail() method has its own try-catch block.
In effect - it looks like below - is there a more beautiful way of writing this?
try {
foo;
}
catch {
try{
sendEmail();
}
catch {
log(e.message);
}
}
If you want something "more elegant", one simple suggestion is to have your sendEmail helper method catch and log the email exceptions. (I don't imagine you want the exceptions to propagate ... or do some other recovery ...)
However, there is something more important to say. What you are implementing here is the wrong approach to reporting errors.
If something goes badly wrong with your application there is a chance that you will SPAM the administrator with multiple emails reporting the same problem over, and over, and over ...
By sending emails from deep within your code, you are making it hard for the administrator to integrate your application's error reporting.
A better approach is to report the problem via a Java logging frame such as Log4J. If the administrator wants to he / she can configure some kind of monitoring system like LogWatch, Nagios, etc, etc. Such a monitoring system will detect and classify errors, anomalies, etc (like your application's errors) in the various logger streams, de-dup them, and if the administrator configures it send a notification via email, pager or whatever.
Java can have nested try / catch blocks.
If you'd like, you can move the try / catch sendmail block to another method. When the try / catch blocks are more complex, it will make the code easier to understand.