在Java中维护堆栈跟踪的同时向抛出异常添加自定义消息

时间:2012-09-24 15:40:06

标签: java exception exception-handling

我有一小段代码贯穿一些事务处理。每个事务都标有一个事务编号,该事务编号由外部程序生成,不一定按顺序排序。当我在处理代码中捕获异常时,我将它抛到主类并将其记录下来以供稍后查看。我想将事务编号添加到此抛出的异常中。是否可以在保持正确的堆栈跟踪的同时执行此操作?

例如:

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

7 个答案:

答案 0 :(得分:76)

尝试:

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

答案 1 :(得分:13)

异常通常是不可变的:您在创建消息后无法更改消息。但是,您可以做的是链异常:

throw new TransactionProblemException(transNbr, originalException);

堆栈跟踪看起来像

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

答案 2 :(得分:8)

还有一个Exception构造函数,它也包含cause参数:Exception(String message, Throwable t)

您可以使用它来传播堆栈跟踪:

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

答案 3 :(得分:2)

你可以在扩展Exception时使用super

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

答案 4 :(得分:0)

您可以通过以下方式使用例外消息: -

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

答案 5 :(得分:0)

下面的代码是为我工作的一个简单示例。让我将函数main称为父函数,将divide称为子函数。
基本上,如果子功能中发生异常,首先通过在子级中捕获Exception,我就会在我的自定义消息 中抛出新的异常(供父级调用)。

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

如果之间出现错误,最后一行return x将不会运行。

答案 6 :(得分:0)

您可以编写一个从 Exception 扩展的 Exception 类并添加这样的属性:` 公共类 PaymentException 扩展异常 { 公共对象数据;

public PaymentException(Throwable cause) {
    super(cause);
}

public void setData(Object o) {
    data = o;
}
public Object getData() {
    return data;
}

}`