Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I print the argument value that caused Exception in Java?

I am writing a parser for csv-files, and sometimes I get NumberFormatException. Is there an easy way to print the argument value that caused the exception?

For the moment do I have many try-catch blocks that look like this:

String ean;
String price;

try {
    builder.ean(Long.parseLong(ean));
} catch (NumberFormatException e) {
    System.out.println("EAN: " + ean);
    e.printStackTrace();
}

try {
    builder.price(new BigDecimal(price));
} catch (NumberFormatException e) {
    System.out.println("Price: " + price);
    e.printStackTrace();
}

I would like to be able to write something like:

try {
    builder.ean(Long.parseLong(ean));
} catch (NumberFormatException e) {
    e.printMethod();    // Long.parseLong()
    e.printArgument();  // should print the string ean "99013241.23"
    e.printStackTrace();
}

Is there any way that I at least can improve my code? And do this kind of printing/logging more programmatically?

UPDATE: I tried to implement what Joachim Sauer answered, but I don't know if I got everything right or if I could improve it. Please give me some feedback. Here is my code:

public class TrackException extends NumberFormatException {
    private final String arg;
    private final String method;

    public TrackException (String arg, String method) {
        this.arg = arg;
        this.method = method;
    }

    public void printArg() {
        System.err.println("Argument: " + arg);
    }

    public void printMethod() {
        System.err.println("Method: " + method);
    }
}

The Wrapper class:

import java.math.BigDecimal;
public class TrackEx {
    public static Long parseLong(String arg) throws TrackException {
        try {
            return Long.parseLong(arg);
        } catch (NumberFormatException e) {
            throw new TrackException(arg, "Long.parseLong");
        }
    }

    public static BigDecimal createBigDecimal(String arg) throws TrackException {
        try {
            return new BigDecimal(arg);
        } catch (NumberFormatException e) {
            throw new TrackException(arg, "BigDecimal.<init>");
        }
    }
}

Example of use:

try {
    builder.ean(TrackEx.createBigDecimal(ean));
    builder.price(TrackEx.createBigDecimal(price));
} catch (TrackException e) {
    e.printArg();
    e.printMethod();
}

EDIT: Same question but for .NET: In a .net Exception how to get a stacktrace with argument values

like image 371
Jonas Avatar asked Dec 13 '22 23:12

Jonas


1 Answers

You can easily implement such detailed information on custom-written exceptions, but most existing exceptions don't provide much more than a detail message and a causing exception.

For example you could wrap all your number parsing needs into a utility class that catches the NumberFormatException and throws a custom exception instead (possibly extending NumberFormatException).

An example where the some additional information is carried via the exception is SQLException which has a getErrorCode() and a getSQLState() method.

like image 164
Joachim Sauer Avatar answered May 24 '23 18:05

Joachim Sauer