web-dev-qa-db-fra.com

Exception.getMessage () est null

Dans mon code Java, il vérifie la condition !null et génère une variable Exception.

Par exemple 

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());
}

Mais dans les journaux, je reçois:

Some Error null

Pourquoi le e.getMessagenull?

49
Revathi

Vous attrapez une exception autre que celle que votre code crée et jette explicitement1. L'exception que vous attrapez n'a pas de message. Vous devez consigner toute l’exception, pas seulement le message de l’exception. (Entre autres choses, cela vous indiquerait quelle est la classe réelle de l'exception interceptée et où l'exception a été créée/levée.)

Étant donné que l'exception ne contient pas de message, je suppose que c'est un NPE causé par stud ou acc nul, ou par stud.getCall() retournant null ... ou quelque chose du genre. Une NullPointerException générée de manière native (c'est-à-dire par la machine virtuelle Java) a un message null2.


Lancer Java.lang.Exception est une mauvaise pratique

Votre problème illustre pourquoi il est généralement une mauvaise idée de créer/lancer Exception 

Lorsque vous lancez Exception, il devient presque impossible de faire la distinction entre cette exception et d'autres exceptions (inattendues) dans une clause catch. Et c’est ce qui s’est passé ici: vous avez capté la mauvaise exception.

Vous devriez choisir une exception plus spécifique et, s'il n'en existe aucune, mettre en œuvre une de vos propres.


1 - Vous pouvez également utiliser e.printStackTrace(), un appel de l’enregistreur ou un débogueur pour déterminer quelle exception vous avez réellement interceptée.

2 - Ce n'est pas vrai sur Android. Là, un NPE contient un message utile qui donne des informations contextuelles.

41
Stephen C

Essayez d’imprimer l’exception, pas seulement le message, comme

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

et voir ce qu'il fait. Imprimer juste le message est une recette pour la confusion. En enregistrant uniquement le message, vous jetez la trace de la pile avec le numéro de ligne qui pointe vers l'emplacement à l'origine de l'exception. Et maintenant, vous avez découvert que toutes les exceptions n'incluent pas de message.

Lancer la nouvelle exception est très mauvais, car vous jetez le type d'origine de l'exception, plus le stacktrace de l'exception d'origine. Comment comptez-vous trouver ce qui ne va pas quand vous jetez toutes les informations utiles? Si vous devez capturer l'exception pour la consigner ici, puis réexécutez la même exception que celle que vous avez interceptée. Au moins, vous ne perdrez pas le stacktrace. (Vous pouvez également créer une nouvelle exception dans laquelle vous transmettez une référence à l'exception d'origine dans l'appel du constructeur.)

Vous feriez mieux d’utiliser un gestionnaire d’exceptions centralisé, de le laisser consigner et de faire en sorte que des exceptions inattendues restent inattendues jusqu’à ce qu’elles parviennent au gestionnaire. Parce qu'une fois qu'une exception génère une exception inattendue, votre application est en mauvais état, toutes les étapes ultérieures qui s'appuient sur quelque chose que cette partie était censée faire échouent et vous obtenez une cascade d'erreurs.

Voici comment j'ai résolu le même problème, utilisez-le pour voir l'exception: 

"" + e);

cela vous aidera lorsque le programmeur d'origine a lancé un objet Exception sans implémenter .getMessage();

Je blâme Google d’avoir autorisé les objets Exception avec une getMessage(); nulle.

lorsque mon code recevait un Java.lang.NullPointerExceptionit, il en résultait par la suite que la journalisation de mes exceptions échouait sur e.getMessage();

la null de .getMessage(); m'a causé une autre exception non gérée et a bloqué l'application avec un message de fermeture forcée .

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

et je l'ai changé en cette version corrigée:

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

maintenant, il me donne une belle chaîne retournée Java.lang.NullPointerException

10
hamish

C'est tard pour le parti mais je parierais que stud est null et que l'exception que vous obtenez est NullPointerException à if (stud.getCall().... C’est l’une des exceptions qui tendent à ne pas avoir de message, c’est-à-dire nul.

1
bestsss

Je voulais commenter la réponse de "" + e de hamish mais je n'ai pas assez de points de réputation ...

Il vaut mieux utiliser e.toString() au lieu de "" + e. Le résultat est identique, mais en interne, ce dernier peut faire plus de travail avec une concaténation inutile, impliquant la création d'un StringBuilder, l'ajout de la chaîne vide, l'ajout du résultat de e.toString (), puis sa conversion en chaîne. Voir "3. Addition Operator" de https://www.baeldung.com/Java-strings-concatenation pour plus d'informations sur l'utilisation de StringBuilder sous les couvertures.

En ce qui concerne le problème initial, je suggérerais d'utiliser e.getString () (ou mieux encore, tracez une pile complète) au lieu de simplement e.getMessage (). Pour certaines exceptions, le message n'a pas de sens sans connaître le type d'exception. Par exemple, e.getMessage () renvoie "-1" alors que e.toString () renvoie "ArrayIndexOutOfBoundsException: -1". Que préféreriez-vous voir dans vos journaux? :-)

0
Mr Weasel

Le code semble bien comprendre la syntaxe et e.getMessage () ne doit pas être nul, j'ai compilé le même code et imprimé le résultat sur la console. Il est affiché sous la forme "Some ErrorData is null", ce qui est correct. Maintenant, soit il y a un problème avec votre enregistreur, soit vous regardez peut-être la mauvaise ligne dans le fichier enregistreur. 

quel peut être le problème avec l'enregistreur

Cela dépend complètement de quel enregistreur utilisez-vous? Avez-vous remplacé les méthodes de looger.error ()? Cependant, il est certain que e.getMessage () n'est pas null dans le bloc catch. Vous pouvez également essayer cela en imprimant e.geMessage () sur la console dans le bloc catch.

0
Zohaib

Avant d'appeler getMessage (), appelez printStackTrace (). cette méthode 

écrit une représentation imprimable de la trace de pile de ce Throwable dans le flux System.err.

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());
}
0
Mehdi Hamin

J'espère que cela pourrait vous aider ....

si vous souhaitez imprimer le message "Les données sont nulles", essayez d'utiliser le nom de votre propre classe dans laquelle vous avez écrit ce code plutôt que d'utiliser la classe "Exception" de Build-in. .si le nom de la classe est "DemoClass" (la classe où vous avez écrit ce code), écrivez comme ceci:

 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());}

et si vous relancez, n'oubliez pas de mentionner "jette DemoClass" à côté de votre fonction (où ce code est écrit):

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