31

I have a generic function that prints exceptions (using log4j):

private void _showErrorMessage(Exception e) {
    log.error(e.getClass() + ": " +  e.getMessage() + ": " + e.getCause() + "\n" +  e.getStackTrace().toString());
}

Instead of seeing the stack trace I'm seeing:

[Ljava.lang.StackTraceElement;@49af7e68

How can I view the stack trace of the exception properly?

update

log.error(e) <- shows the error, but doesn't show stack trace

Community
  • 1
  • 1
ufk
  • 30,912
  • 70
  • 235
  • 386
  • 8
    Calling `log.error(e)` in log4j calls the wrong version of the method ( http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/Category.html#error%28java.lang.Object%29 ). The JavaDoc for this method even mentions that fact: "WARNING Note that passing a Throwable to this method will print the name of the Throwable but no stack trace. To print a stack trace use the error(Object, Throwable) form instead." – Joachim Sauer Feb 11 '10 at 16:01
  • 5
    call log.error(e,e) will do the job ;) – Guillaume Feb 11 '10 at 17:24

7 Answers7

77

Your logging framework should have the ability to log exceptions, so simply passing the exception to the proper .error(Object, Throwable) call should be enough:

If your logging framework can't do that, or you need the stack trace in a String for any other reason, then it becomes a bit harder. You'll have to create a PrintWriter wrapping a StringWriter and call .printStackTrace() on the Exception:

StringWriter sw = new StringWriter();
ex.printStackTrace(new PrintWriter(sw));
String stacktrace = sw.toString();
Joachim Sauer
  • 302,674
  • 57
  • 556
  • 614
  • when i pass the exception to log.error, it just shows the error message with no stack trace. using log4j – ufk Feb 11 '10 at 15:36
  • 1
    That means that you called the wrong version. There's `error(Object)` and `error(Object,Throwable)`. Calling the first version will effectively call `toString()`. – Joachim Sauer Feb 11 '10 at 16:02
  • @Joachim, the way to handle exceptions with log4j - which he mentions to be using - is to log using log.error(String, Throwable) and let log4j handle the stack trace. The asker clearly isn't aware of that. – Thorbjørn Ravn Andersen Feb 11 '10 at 20:19
  • @Joachim, sorry. It appears that the log4j-information was added in the edit made after your answer. – Thorbjørn Ravn Andersen Feb 11 '10 at 20:20
18

Have you tried?

private void _showErrorMessage(Exception e) {
    log.error("Hey! got an exception", e);
}
Paul McKenzie
  • 19,646
  • 25
  • 76
  • 120
14

I use the ExceptionUtils#getFullStackTrace method of Jakarta Commons Lang

Joachim Sauer
  • 302,674
  • 57
  • 556
  • 614
Guillaume
  • 5,488
  • 11
  • 47
  • 83
  • 2
    @codemonkey, you can search yourself for the ExceptionUtils in your favourite search engine: my answer was to use an existing library. I can't maintain all links I have posted in SO. Now, the answer from Joachim sounds better than mine :) Please read it. – Guillaume Jan 30 '12 at 07:50
5

Throwable.getStackTrace returns an array of StackTraceElements, hence the toString method is returning a textual representation of the array itself.

In order to actually retrieve the stack trace information, one would have to go through each StackTraceElement to get more information.

coobird
  • 159,216
  • 35
  • 211
  • 226
4

You could also look at the Guava libraries from Google.

Throwables.getStackTraceAsString(Throwable throwable)

gpampara
  • 11,989
  • 3
  • 27
  • 26
1

Exception Stacktrace logging shows two methods for this purpose, one based on Apache Commons and another using the standard JDK method.

Marco C.
  • 41
  • 6
1

The exact answer to your question is that you should call Log4J like this:

private void _showErrorMessage(Exception e) {
    log.error(e.getClass() + ": " +  e.getMessage() + ": " + e.getCause(), e);
}

Although I would dispense with the call to e.getCause() because the stacktrace will give that to you anyway, so:

private void _showErrorMessage(Exception e) {
    log.error(e.getClass() + ": " +  e.getMessage(), e);
}

ExceptionUtils is fine if you really need a string of the stacktrace, but since you are using Log4J, you lose a lot by not utilizing its built in exception handling.

Yishai
  • 90,445
  • 31
  • 189
  • 263