Add custom message to thrown exception while maintaining stack trace in Java

I have a small piece of code that runs through some transactions for processing. Each transaction is marked with a transaction number, which is generated by an outside program and is not necessarily sequenced. When I catch an Exception in the processing code I am throwing it up to the main class and logging it for review later. I'd like to add the transaction number to this thrown Exception. Is it possible to do this while still maintaining the correct stack trace?

For Example:

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

Solution 1:

Try:

throw new Exception("transction: " + transNbr, E); 

Solution 2:

Exceptions are usually immutable: you can't change their message after they've been created. What you can do, though, is chain exceptions:

throw new TransactionProblemException(transNbr, originalException);

The stack trace will look like

TransactionProblemException : transNbr
at ...
at ...
caused by OriginalException ...
at ...
at ...

Solution 3:

There is an Exception constructor that takes also the cause argument: Exception(String message, Throwable t).

You can use it to propagate the stacktrace:

try{
    //...
}catch(Exception E){
    if(!transNbr.equals("")){
        throw new Exception("transaction: " + transNbr, E); 
    }
    //...
}

Solution 4:

you can use super while extending 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);
}

}

}

source