Exception.getMessage() is null

JavaException

Java Problem Overview


Inside my Java code, it is checking for !null condition and throwing an Exception.

For example

try
{
    if (stud.getCall() != null)
        acc.Call = stud.getCall().toString();
    else
        throw new Exception("Data is null");
}
catch (Exception e)
{
    logger.error("Some Error" + e.getMessage());
    throw new Exception("Please check the Manatadatory Field is Missing" + e.getMessage());
}

But in the logs I am getting:

Some Error null

Why is the e.getMessage null?

Java Solutions


Solution 1 - Java

You are catching a different exception to the one that your code is explicitly creating and throwing1. The exception that you are catching doesn't have a message.

You need to log the entire exception, not just the exception's message. Among other things, that would tell you what the caught exception's actual class is and where the exception was created/thrown.

Based on the fact that the exception doesn't have a message, I'd guess that it is an NPE caused by stud or acc being null, or by stud.getCall() returning null ... or something like that. A NullPointerException generated natively (i.e. by the JVM) has a null message2.


Throwing java.lang.Exception is Bad Practice

Your problem illustrates why it is generally speaking a bad idea to create/throw Exception

When you throw Exception it becomes next to impossible to discriminate between it and other (unexpected) exceptions in a catch clause. And that is what has happened here: you've caught the wrong exception.

You should pick a more specific exception, and if no appropriate one exists, implement one of your own.


1 - You could use e.printStackTrace(), a logger call, or a debugger to see which exception you have actually caught.
2 - This is not true on Android. There, an NPE has a helpful message that gives contextual information. It is also no longer true in Java 14 and later; see https://openjdk.java.net/projects/jdk/14/ and https://openjdk.java.net/jeps/358</sup>

Solution 2 - Java

The stack trace is getting written to the log while a message gets written to stdout. My assumption is you don't have permission to see whatever stdout gets written to, so now there is nothing to go on. (Even if you do have rights to see it now you have two separate things to piece together.)

Most logging libraries can log the stacktrace. That way you can keep all the useful information together, adding the exception to the log, not just the message, like

logger.error("caught exception while doing whatever", e);

The stack trace has the exception message, plus the line number that points to the place that caused the exception, and shows you every call along the way, so it's really helpful. And now you've found out not all exceptions include a message.

If whatever you are logging to doesn't handle writing the exception stack trace information, there is code to write the stacktrace as a string here.

The way the posted code throws a new exception is very bad, because you are throwing away the original type of the exception, plus the stacktrace of the original exception. How do you expect to figure out what went wrong when you throw away all the helpful information? If you must catch the exception to log it here, then rethrow the same exception that you caught, or pass the original exception to the new exception as the cause (check out the Throwable constructor arguments), at least that way you don't lose the stacktrace.

You would be better off using a centralized exception handler, letting that do the logging, and have unexpected exceptions go uncaught until they get to the handler. Because once something throws an unexpected exception, your application is in a bad state, any subsequent steps that rely on something this part was supposed to do will fail, and you will get a cascade of errors.

Solution 3 - Java

This is how I fixed the same problem, use this to see the exception:

"" + e);

this will help you when the original programmer threw an Exception object without implementing .getMessage();

I blame Google for allowing Exception objects with null getMessage();

when my code was getting a java.lang.NullPointerException it was subsequently causing my exception logging to fail on e.getMessage();

the null from .getMessage(); caused me another unhandled exception and crashed the app with force close message. so it was this:

Log.e("MainLogger.Run.Exception", e.getMessage());

and I changed it to this Corrected version:

Log.e("MainLogger.Run.Exception", "" + e);

now it gives me a nice string returned java.lang.NullPointerException

Solution 4 - Java

Wanted to comment on hamish's "" + e answer but I don't have enough reputation points...

It's better to just use e.toString() instead of "" + e. The result is the same, but internally, the latter may be doing more work with unnecessary concatenation, involving creating a StringBuilder, appending the blank string, appending the result of e.toString() then converting back to a String. See "3. Addition Operator" of https://www.baeldung.com/java-strings-concatenation for details about StringBuilder being used under the covers.

Regarding the original problem, I'd suggest using e.getString() (or even better, do a full stack trace) instead of just e.getMessage(). For some exceptions the message doesn't make sense without knowing the exception type. An example I've encountered is where e.getMessage() returns "-1", but e.toString() returns "ArrayIndexOutOfBoundsException: -1". Which would you prefer to see in your logs? :-)

Solution 5 - Java

This is late to the party but I'd bet stud is null and the exception you get is NullPointerException at if (stud.getCall()..... It's one of the exception that tend not to have message, i.e. null.

Solution 6 - Java

In my case it was returning the wrong Exception with a null message, because I wrapped the result of the method call in an Optional variable:

It was a call to a MongoRepository database operation:

 Optional<CustomerDB> result = Optional.of(repository.findByToken(token));

The function "repository.findByToken(token)" was just returning a CustomerDB object.

I changed the code line to:

CustomerDB result = repository.findByToken(token);

And I got the right exception with the message.

Solution 7 - Java

The code seems fine syntax wise and e.getMessage() should not be null, I compiled the same code and printed the output on console, it printed as "Some ErrorData is null" which is fine. Now either there is issue with your logger or you might be looking at the wrong line in logger file.

>what can be the issue with logger

It completely depends upon which logger are you using ? Have you overridden the methods of looger.error() ? However it is for sure that e.getMessage() is not null in the catch block. You can also try that by printing e.geMessage() on console in the catch block.

Solution 8 - Java

Before call getMessage() call printStackTrace(). this method

> writes a printable representation of this Throwable's stack trace to > the System.err stream.

try
{
    if (stud.getCall() != null)
        acc.Call = stud.getCall().toString();
    else
        throw new Exception("Data is null");
}
catch (Exception e)
{
    e.printStackTrace();
    logger.error("Some Error" + e.getMessage());
    throw new Exception("Please check the Manatadatory Field is Missing" + e.getMessage());
}

Solution 9 - Java

I hope this might help you....

if you want to print the message "Data is null", then instead of using the Build-in class "Exception", try to use the name of your own class where you have wrote this code. for example: if the class name is "DemoClass" (the class where you wrote this code), then write like this:

 try{
if (stud.getCall() != null)
    acc.Call = stud.getCall().toString();
else
    throw new DemoClass("Data is null");
}
catch (DemoClass e){
logger.error("Some Error" + e.getMessage());}

and if you are re-throwing, then don't forget to mention "throws DemoClass" by the side of your function (where this code is written):

 throw new DemoClass("Please check the Mandatory Field is Missing" + e.getMessage());

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRevathiView Question on Stackoverflow
Solution 1 - JavaStephen CView Answer on Stackoverflow
Solution 2 - Javaпутин некультурная свиньяView Answer on Stackoverflow
Solution 3 - JavahamishView Answer on Stackoverflow
Solution 4 - JavaMr WeaselView Answer on Stackoverflow
Solution 5 - JavabestsssView Answer on Stackoverflow
Solution 6 - JavaLaura LiparuloView Answer on Stackoverflow
Solution 7 - JavaZohaibView Answer on Stackoverflow
Solution 8 - JavaMehdi HaminView Answer on Stackoverflow
Solution 9 - JavaHrushikeshView Answer on Stackoverflow