32

I'm trying to fix an issue, in my application I have this code

try {
  object1.method1();
} catch(Exception ex) {
   JOptionPane.showMessageDialog(nulll, "Error: "+ex.getMessage());
}

and the object1 would do something like that:

public void method1() {
   //some code...
   throw new RuntimeException("Cannot move file");
}

I get a messsage in my option pane like this: Error: java.lang.RuntimeException: Cannot move file

but I used getMessage and not toString method, so the name of the class shouldn´t appear, right?

What I am doing wrong? I already tryied with a lot of exceptions, even Exception itself. I'm looking to solve this no without the need to implement my own Exception subclass

PROBLEM SOLVED - thank you all!

The try and catch were actually being called in get() method from SwingWorker which constructs an ExecutionException with my exception thrown from doInBackground() I fixed doing this:

@Override
protected void done() {
    try {
        Object u = (Object) get();
        //do whatever u want
    } catch(ExecutionException ex) {
        JOptionPane.showMessageDialog(null, "Error: "+ex.getCause().getMessage());
    } catch(Exception ex) {
        JOptionPane.showMessageDialog(null, "Error: "+ex.getMessage());
    }
}
4
  • 1
    Sounds odd - can you reproduce this in a short but complete program? Commented Jan 26, 2012 at 12:01
  • Can you add e.printStackTrace() as well in catch? It looks like @dacwe is right. Commented Jan 26, 2012 at 12:04
  • Looking at the stack trace I can see that the problem might be the Swing Worker.......the try { } is actually calling get() from swing worker method done() and the exception is thrown in doInBackGround Commented Jan 26, 2012 at 12:45
  • It is questionable whether you should report the message text of an exception in the GUI at all. Commented Mar 24, 2016 at 17:20

2 Answers 2

35

I think you are wrapping your exception in another exception (which isn't in your code above). If you try out this code:

public static void main(String[] args) {
    try {
        throw new RuntimeException("Cannot move file");
    } catch (Exception ex) {
        JOptionPane.showMessageDialog(null, "Error: " + ex.getMessage());
    }
}

...you will see a popup that says exactly what you want.


However, to solve your problem (the wrapped exception) you need get to the "root" exception with the "correct" message. To do this you need to create a own recursive method getRootCause:

public static void main(String[] args) {
    try {
        throw new Exception(new RuntimeException("Cannot move file"));
    } catch (Exception ex) {
        JOptionPane.showMessageDialog(null,
                                      "Error: " + getRootCause(ex).getMessage());
    }
}

public static Throwable getRootCause(Throwable throwable) {
    if (throwable.getCause() != null)
        return getRootCause(throwable.getCause());

    return throwable;
}

Note: Unwrapping exceptions like this however, sort of breaks the abstractions. I encourage you to find out why the exception is wrapped and ask yourself if it makes sense.

Sign up to request clarification or add additional context in comments.

5 Comments

Your getRootCause method is not protected against infinite recursion.
@Perception, Unless the throwable has itself as its cause or you have some other super weird cyclic chain of causes you shouldn't need to worry about it.
@aioobe - True, those are the primary reasons to check. But it's not as rare an occurrence as you might think.
I disagree. I've never run across such situation. Actually, not even the designers of the Throwable-class takes that scenario into account considering the printStackTrace method.
Use org.apache.commons.lang3.exception.ExceptionUtils.getRootCause() instead of rolling your own
8

My guess is that you've got something in method1 which wraps one exception in another, and uses the toString() of the nested exception as the message of the wrapper. I suggest you take a copy of your project, and remove as much as you can while keeping the problem, until you've got a short but complete program which demonstrates it - at which point either it'll be clear what's going on, or we'll be in a better position to help fix it.

Here's a short but complete program which demonstrates RuntimeException.getMessage() behaving correctly:

public class Test {
    public static void main(String[] args) {
        try {
            failingMethod();
        } catch (Exception e) {
            System.out.println("Error: " + e.getMessage());
        }
    }       

    private static void failingMethod() {
        throw new RuntimeException("Just the message");
    }
}

Output:

Error: Just the message

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.