J'ai un petit morceau de code qui traverse certaines transactions pour le traitement. Chaque transaction est marquée d'un numéro de transaction, généré par un programme externe et non nécessairement séquencé. Lorsque j'attrape une exception dans le code de traitement, je la renvoie à la classe principale et la consulte pour une revue ultérieure. J'aimerais ajouter le numéro de transaction à cette exception levée. Est-il possible de faire cela tout en maintenant la trace de pile correcte?
Par exemple:
public static void main(String[] args) {
try{
processMessage();
}catch(Exception E){
E.printStackTrace();
}
}
private static void processMessage() throws Exception{
String transNbr = "";
try{
transNbr = "2345";
throw new Exception();
}catch(Exception E){
if(!transNbr.equals("")){
//stack trace originates from here, not from actual exception
throw new Exception("transction: " + transNbr);
}else{
//stack trace gets passed correctly but no custom message available
throw E;
}
}
}
Essayer:
throw new Exception("transction: " + transNbr, E);
Les exceptions sont généralement immuables: vous ne pouvez pas modifier leur message après leur création. Ce que vous pouvez faire, cependant, ce sont des exceptions en chaîne:
throw new TransactionProblemException(transNbr, originalException);
La trace de la pile ressemblera à
TransactionProblemException : transNbr
at ...
at ...
caused by OriginalException ...
at ...
at ...
Il existe un constructeur Exception
qui prend également l'argument cause: Exception (message String, Throwable t) .
Vous pouvez l'utiliser pour propager le stacktrace:
try{
//...
}catch(Exception E){
if(!transNbr.equals("")){
throw new Exception("transaction: " + transNbr, E);
}
//...
}
vous pouvez utiliser super en prolongeant Exception
if (pass.length() < minPassLength)
throw new InvalidPassException("The password provided is too short");
} catch (NullPointerException e) {
throw new InvalidPassException("No password provided", e);
}
// A custom business exception
class InvalidPassException extends Exception {
InvalidPassException() {
}
InvalidPassException(String message) {
super(message);
}
InvalidPassException(String message, Throwable cause) {
super(message, cause);
}
}
}
Vous pouvez utiliser votre message d'exception par: -
public class MyNullPointException extends NullPointerException {
private ExceptionCodes exceptionCodesCode;
public MyNullPointException(ExceptionCodes code) {
this.exceptionCodesCode=code;
}
@Override
public String getMessage() {
return exceptionCodesCode.getCode();
}
public class enum ExceptionCodes {
COULD_NOT_SAVE_RECORD ("cityId:001(could.not.save.record)"),
NULL_POINT_EXCEPTION_RECORD ("cityId:002(null.point.exception.record)"),
COULD_NOT_DELETE_RECORD ("cityId:003(could.not.delete.record)");
private String code;
private ExceptionCodes(String code) {
this.code = code;
}
public String getCode() {
return code;
}
}
Le code suivant est un exemple simple qui a fonctionné pour moi. Laissez-moi appeler la fonction main
en tant que fonction parent et divide
en tant que fonction enfant.
En gros, je lève une nouvelle exception avec mon message personnalisé(pour l'appel du parent) si une exception se produit dans la fonction enfant en saisissant d'abord l'exception dans l'enfant.
class Main {
public static void main(String args[]) {
try{
long ans=divide(0);
System.out.println("answer="+ans);
}
catch(Exception e){
System.out.println("got exception:"+e.getMessage());
}
}
public static long divide(int num) throws Exception{
long x=-1;
try {
x=5/num;
}
catch (Exception e){
throw new Exception("Error occured in divide for number:"+num+"Error:"+e.getMessage());
}
return x;
}
}
la dernière ligne return x
ne fonctionnera pas si une erreur survient quelque part entre les deux.