I need to process an exception message when any exception is caught in Java.
I am working on a Database Connection class. When I give wrong details like username, password, host name, sid, etc, the control goes to catch block and gives an error. I would like to get this error message on the JSP side and redirect to the same page with that error message. However, when I get the error message in Java, it always takes a null value.
My code example is here.
String errorMessage = null;
try{
// CODE Where Exception occure
}catch(SQLException se){
errorMessage = se.getMessage();
}catch(Exception e){
System. out.println("In Exception block.");
errorMessage = e.getMessage();
}finally{
System.out.println(errorMessage);
}
It will go to Exception block but the errorMessage is null.
At first, the answer of #Artem Moskalev should be right in most ways. In your case, you'd said:
It will goes to Exception block but the errorMessage is null.
So, let's try two cases to debug the behavior:
First:
class Test1
{
public static void main (String[] args) throws java.lang.Exception
{
String errorMessage = null;
try{
throw(new Exception("Let's throw some exception message here"));
}catch(Exception e){
System.out.println("In Exception block.");
errorMessage = e.getMessage();
}finally{
System.out.println(errorMessage);
}
}
}
Output:
In Exception block.
Let's throw some exception message here
Seems to work like you expected.
Second:
class Test2
{
public static void main (String[] args) throws java.lang.Exception
{
// String errorMessage = null;
// To make the difference between non-initialized value
// and assigned null value clearer in this case,
// we will set the errorMessage to some standard string on initialization
String errorMessage = "Some standard error message";
try{
throw(new Exception());
}catch(Exception e){
System.out.println("In Exception block.");
errorMessage = e.getMessage();
}finally{
System.out.println(errorMessage);
}
}
}
Output:
In Exception block.
null
Why is that? Because you're accessing e.getMessage(), but if the message is emtpy e.getMessage() will return null. So the null isn't from the initialization, but from the return value of e.getMessage(), when e doesn't have any error message (for example if there is a NullPointerException thrown).
This block is always executed:
...finally{
System.out.println(errorMessage);
}
If your errorMessage has not been assigned any other value before (ie. no exception thrown in your try clause) - System.out.println will print you the errorMessage value which is null.
your catch(Exception e) block will catch all exceptions (other than SQLException which you are specifically catching above). Some exceptions e.g. NullPointerException can have null details message i.e. e.getMessage() can retun null. So it is better to print the exception details like exception type also- use e.ToString() or e.printStacktrace() for more details.
Related
void connectOverNetwork() throws Exception {
try {
final JSONObject response = make network call;
if (!response.getBoolean(SUCCESS)) {
LOG.error("--- foo message ---");
throw new Exception("message replied with error");
}
} catch (final Exception e) {
LOG.error("---- bar message ---");
throw new SvcException("failed to connect over network");
}
}
In the code above, I am throwing an exception with a failure message.
At the same time, I am also throwing an error on failure to connect over the network.
But, if I throw an exception for !success it gets caught again, causing duplicate logging. I do not want to print bar message, if I only want to log foo message.
How to prevent it from happening?
Validate the response after the try-catch statement.
JSONObject response = null;
try {
response = /* make network call */;
} catch (final Exception e) {
LOG.error("---- bar message ---");
throw new SvcException("failed to connect over network");
}
if (!response.getBoolean(SUCCESS)) {
LOG.error("--- foo message ---");
throw new Exception("message replied with error");
}
I don't recommend catching Exception - it's too general, I suggest you narrow it down to a more specific exception type.
What if you move it outside the try block.. Anyway, the reason for the first try..catch is to catch any Exception from the network call.
JSONObject response = null;
try {
response = make network call;
} catch (final Exception e) {
LOG.error("---- bar message ---");
throw new SvcException("failed to connect over network");
}
if (!response.getBoolean(SUCCESS)) {
LOG.error("--- foo message ---");
throw new Exception("message replied with error");
}
First, let me point out a mistake in your code. Your method declares that it throws Exception, but it doesn't. It throws SvcException. So that's what the "throws" clause should say. (You should never say "throws Exception" anyway. You should state explicitly what kind of exception it throws.) The rest of the answer depends on whether or not your vague description "make network call" throws an exception or not.
If it doesn't, your method should look like this:
void connectOverNetwork() throws SvcException {
final JSONObject response = makeNetworkCall();
if (!response.getBoolean(SUCCESS)) {
LOG.error("--- foo message ---");
throw new SvcException("message replied with error");
}
}
But that's unrealistic. Chances are, your "make network call" code throws something like IOException. In this case your code should look like this:
void connectOverNetwork() throws SvcException {
try {
final JSONObject response = makeNetworkCall(); // throws IOException
if (!response.getBoolean(SUCCESS)) {
LOG.error("--- foo message ---");
throw new SvcException("message replied with error");
}
} catch (final IOException e) {
LOG.error("--- foo message ---");
throw new SvcException("failed to connect", e); // wrap e inside SvcException
}
}
Notice that I wrap the caught IOException inside the SvcException. If your SvcException doesn't do that, either rewrite it so that it can, or call its initCause() method before throwing it. You should always include the original exception when reThrowing a different exception.
Also notice that I don't bother throwing, then catching and rethrowing an IOException. When I detect failure. I just throw the exception that I need to throw. This means I need to log the foo message in two separate places. For most things, repeating a line of code should be avoided, but for logging, this is fine.
But this code is a bit messy. I would clean it up by separating the test for success from the possible IOException. So I would write it like this:
void connectOverNetwork() throws SvcException {
JSONObject response; // no need to initialize this.
try {
response = makeNetworkCall(); // throws IOException
} catch (final IOException e) {
LOG.error("--- foo message ---");
throw new SvcException("failed to connect", e); // wrap e inside SvcException
}
if (!response.getBoolean(SUCCESS)) {
LOG.error("--- foo message ---");
throw new SvcException("message replied with error");
}
}
Notice here that response is declared before the try loop. It's not initialized because there's no way it will reach the !response.getBoolean(SUCCESS) test without a value. If makeNetworkCall() throws an exception, it won't even reach that line.
Create your own exception type and don't catch it.
try {
do stuff
if (condition)
throw new MyCustomException("error")
} catch (IOException e) {
log and rethrow
}
I want to throw an exception and to display it. In my IF block I throw the exception. Do I have to store the exception to pass it as a variable in the method which precedes.
if(count !=0) {
throw new Exception();
eventLogger.logError("The count is not zero",e)
}
else{
// do something else
}
The logger has Throwable error as a parameter.
logError(String description, Throwable error);
How can I pass the exception I thrown to this method
Once the Exception is thrown, your program stops running. Thus you have to change the order of your statements.
if(count !=0) {
Exception e = new Exception();
eventLogger.logError("The count is not zero",e)
throw e;
}
else{
// do something else
}
As you can read in the Java API the class Exception
extends Throwable
EDIT
As Zabuza mentioned, it's possible to handle the exception in a try- catch block. This would be a more elegant way:
try{
if(count !=0) {
throw new Exception();
}else{
// do something else
}
}
catch(Exception e){
eventLogger.logError("The count is not zero",e)
}
Exceptions don't work like this. Once you throw an exception, the code gets interrupted and doesn't run any further. You can access the thrown exception in the next try-catch block like this:
try{
//code that may throws an exception like this:
throw new Exception();
}catch(Exception e){
eventLogger.logError("Your message", e);
}
If you wannt to log the exception before you catch it you have to first create it, then log it and finally throw it.
Exception e = new Exception();
eventLogger.logError("your message", e);
throw e;
The logger will never be reached in your example, as the Exception is thrown a line before. To log an error, you'd do so in the catch part of your try - catch block
try {
throw new Exception();
} catch (Exception e) {
eventLogger.logError("The count is not zero",e);
}
When you throw an error, you terminate the execution of the method. That makes your second statement unreachable.
In your method header, declare methodName() throws Exception. Now, wherever this method is called, you know that there is a risk it may throw an exception.
try{
methodName();
}
catch(Exception e){
eventLogger.log(e);
}
Switching the order will not help you because e is not understood.
Exception is throwable so, once throw new Exception(); is executed then
eventLogger.logError("The count is not zero",e)
above statement will be come unreachable. So you need to complete all operations(like method calls.. etc.) before throwing an exception. And you should write the exception printing code in a catch clause.
So finally you need to change the code as follows...
try{
if(count !=0) {
// do method callings
throw new Exception();
}else{
// write alternative flow here
}
}
catch(Exception exception){
logger.error(exception);
eventLogger.logError("The count is not zero",exception);
}
If what you are doing will throw an exception (e.g. calling File.open() or something) then wrap it in a try-catch-finally
bool errorOccurred = false;
try {
// do things that can cause errors here.
} catch (Exception e) {
// things in here happen immediately after an exception in try-block
eventLogger.logError("The count is not zero", e);
errorOccurred = true;
} finally {
// always happens after a try, regaurdless or exception thrown or not
if (errorOccurred) {
/* report error to user or something else */
} else {
/* finish up */
}
}
but if you just want to log that specific condition was met, you can make your own exception object, and pass it to the error logging method without using try catch
if (count != 0) {
Exception ex = new Exception();
// set the properties you need set on ex here
errorLogger.logError("The count is not zero", ex);
} else {
// do something else
}
For the second option, you can use different subclasses the inherit from Exception, or you can even make your own implementation.
I have below code.
The question is :
Is there a better way to handle exception for below use case other than this ?
My particular interest is using handleException method.
public void checkSomeBehaviour() throws Exception{
try{
someBusinessValidation() ;
//this method can throw BusinessValidationException which is subclass of Exception
//BusinessValidationException contains code in getMessage() method
try{
doSomething();
}catch(Exception ex1){
//throw Exception object with specific error code say 123. So this needs to be wrapped in separate try/catch
throw CustomException('123'); //CustomException is subclass of Exception
}
try{
doSomethingElse();
}catch(Exception ex2){
//throw Exception object with specific error code say 456 .So this needs to be wrapped in separate try/catch
throw CustomException('456'); //CustomException is subclass of Exception
}
}
catch(Exception ex){
//Based on Exception type , a common exception needs to be thrown as ValidationException
handleException(ex);
}
}
//this method inspects exception type and does appropriate action accordingly
private void handleException(Exception ex){
if(ex instanceof CustomException){
throw new ValidationException(ex.getCode());
}else if(ex instanceof BusinessValidationException){
throw new ValidationException(ex.getMessage());
}else{
throw new ValidationException(100); //throw code as 100 since this is generalised exception
}
}
Answer is: YES. Java gives you native syntax to do just that (cleaner and simply more appropriate than checking exception classes):
//...your try block
} catch (CustomException ex) {
throw new ValidationException(ex.getCode());
} catch (BusinessValidationException ex) {
throw new ValidationException(ex.getMessage());
} catch (Exception ex) {
throw new ValidationException(100);
}
Just note that you may need to reorder these catch blocks if they extend one another.
If you don't have any business logic between method calls then you can declare errorCode as a variable, change it after method execution and re-throw appropriate exception in catch, e.g.:
public void checkSomeBehavior() throws Exception{
int errorCode = 123;
try{
someBusinessValidation();
doSomething();
errorCode = 456;
doSomethingElse();
}catch(BusinessValidationException bve){
throw new Exception(bve.getMessage());
}catch(Exception e){
throw new Exception(String.valueOf(errorCode));
}
}
If doSomething fails, the value will be 123 and if doSomethingElse fails, the value will be 456.
I find myself coding methods that throw a specified error, but still surrounding the relevant code sections in a try catch, where I use the catch to log a localised error message and re-throw the principal one.
Here is a short example:
public void doWork(String url) throws IOException {
Object target;
try {
target = new target(url); //instantiating this object could potentially not work if the URL is malformed
} catch (MalformedURLException e) {
localErrorMessage(debug, "URL error here"); //log a local message
throw e;
} catch (IOException e) { //in some cases it can throw an IO exception if using a localised file type object.
localErrorMessage(debug, "IO error here"); //log a local message throw e;
}
}
I use this as I can turn off my localised logging (using log4j2), or use it during testing, as a debugging method.
Is this a reasonable practice, or is there a better way to do it?
Just came across a rather confusing exam question, and my lecturer is away on holidays, so I come to StackOverflow begging for help!
The question is as follows :
"Joe has his own JoeConnection class for making connections between his computer and other computers. The class provides the following constructor and instance methods :
JoeConnection( String address ): Make a connection with the URL address.
void writeLn( String text ) : Write text to the JoeConnection.
String readLn( ): Read a line of text from the JoeConnection.
void clode( ) : Close the JoeConnection.
Joe's connections regularly fail and this causes errors. Using proper exception handling, demonstrate how to use Joe's JoeConnection class to
make a JoeConnection with the URL http://students.chat.box
write "Hello world" to the JoeConnection
read in a string from the JoeConnection
close the connection.
The connection handling should provide as man details as possible about the cause of failure and print the stack trace which led to the failure.
I have no idea how to tackle this, but I assume it is something similar to this :
public class Test {
try {
JoeConnection connection = new JoeConnection(http://students.chat.box);
} catch {
connectionError e; printStacktrace();}
}
}
Can anyone please help me figure this out? Thanks a lot.
Without an indication of what exceptions are thrown and why, the only proper exception handling is no handling at all. Don't catch an exception if you don't know how to fix the problem that triggered it.
But the further instructions in your assignment introduce a different notion of "proper." You're supposed to print a stack trace. So catch the exception and print a stack trace. You were on the right track, but your syntax was wrong. Refer back to your textbook and lecture notes to remind yourself what the syntax is for catching exceptions (and for passing strings to functions, for that matter).
try {
JoeConnection connection = new JoeConnection("http://students.chat.box");
connection.writeLn("Hello world");
// etc
} catch (Exception e) {
e.printStackTrace();
}
"Proper exception handling" is a little vague. I agree with #Rob Kennedy's statement that no exception handling is appropriate unless you know why the exception is thrown and what should be done with it. Otherwise, the exception should be allowed to propagate. So, for example:
void foo(String address) throws JoeException {
JoeConnection connection = new JoeConnection(address);
try {
connection.writeLn("Hello World!");
} finally {
// Ensure the connection is closed when finished.
// This happens whether an exception occurs or not.
connection.close();
}
}
If you wanted to catch the exception just to print it, you could do something like this:
void foo(String address) throws JoeException {
try {
JoeConnection connection = new JoeConnection(address);
try {
connection.writeLn("Hello World!");
} finally {
connection.close();
}
} catch (JoeException e) {
e.printStackTrace();
// Don't know what to do about this; rethrow.
throw e;
}
}
There is a subtlety here that even experience Java programmers can miss, though. If an exception occurs while creating the connection, it doesn't need to be closed. If an exception occurs while writing to the connection, it does need to be closed; thus the finally clause. However, the act of closing can also throw an exception. If closing the connection throws an exception, only that exception will be thrown by the try statement. If the finally clause was reached as a result of the writeLn operation throwing an exception, the exception of the writeLn call will be effectively ignored. This is probably not what you want.
Instead, we can try something ugly like this:
void foo(String address) throws JoeException {
try {
JoeConnection connection = new JoeConnection(address);
boolean normalCompletion = false;
try {
connection.writeLn("Hello World!");
normalCompletion = true;
} finally {
if (normalCompletion) {
// The writeLn operation completed normally.
// Propagate an exception thrown by the close operation.
connection.close();
} else {
// The writeLn operation completed abruptly.
// Ignore an exception thrown by the close operation.
try {
connection.close();
} catch (JoeException e) {
/* empty */
}
}
}
} catch (JoeException e) {
e.printStackTrace();
// Don't know what to do about this; rethrow.
throw e;
}
}
This looks (and is) syntactically hideous, but it does show "proper" exception handling of a sort. The language enhancement from Project Coin should clean this up a bit.
For starters, I can help you out with the syntax of what you wrote:
try {
JoeConnection connection = new JoeConnection("http://students.chat.box");
}
catch (JoeConnectionException e) {
e.printStacktrace();
}
I took the liberty of changing the linebreaks and renaming 'connectionError' as JoeConnectionException which looks more conventional to me.
You'll have to do something similar for the readLn, writeLn, and close method calls since it said that the connection regularly fails (i.e. not just while connecting).
Cheers, good luck.
Catching an exception should look like:
try {
JoeConnection conn = new JoeConnection(url);
} catch (YourExceptionClassNameHere e) {
e.printStackTrace();
}
Also: if you want to use a literal String, make sure you include the quotations. (It should be "http://students.chat.box".)
It's good to have a finally as well:
public class Test {
try {
JoeConnection connection = new JoeConnection(http://students.chat.box);
}
catch(Exception e) {
e.printStacktrace();
}
finally {
if(connection != null) {
connection.close();
}
}
}
Typically you handle exceptions if you know what to do with them (this involves error-recovery logic or wrapping an exception and throwing it to a higher level).
Assuming that each method throws an exception, you could do something like this for "maximum detail":
public class Test {
JoeConnection connection = null;
try {
connection = new JoeConnection("http://students.chat.box");
...
...
}
catch(OpenException e) {
System.out.println("Error while opening connection");
e.printStacktrace();
}
catch(WriteException e) {
System.out.println("Error while writing to connection");
e.printStacktrace();
}
catch(ReadException e) {
System.out.println("Error while reading from connection");
e.printStacktrace();
}
finally {
if(connection != null) {
connection.close();
}
}
}