Как я могу напечатать значение аргумента, вызвавшее исключение в Java? - PullRequest
4 голосов
/ 15 марта 2010

Я пишу парсер для csv-файлов, и иногда я получаю NumberFormatException. Есть ли простой способ напечатать значение аргумента, вызвавшее исключение?

На данный момент у меня есть много блоков try-catch, которые выглядят так:

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

Я бы хотел написать что-то вроде:

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

Есть ли способ улучшить мой код? И делают ли этот тип печати / регистрации более программно?

ОБНОВЛЕНИЕ: Я пытался реализовать то, что Йоахим Зауэр ответил, но я не знаю, правильно ли я все понял или смог бы улучшить. Пожалуйста, дайте мне отзыв. Вот мой код:

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

Класс Wrapper:

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

Пример использования:

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

РЕДАКТИРОВАНИЕ: Тот же вопрос, но для .NET: В исключении .net как получить трассировку стека со значениями аргументов

Ответы [ 3 ]

9 голосов
/ 15 марта 2010

Вы можете легко реализовать такую ​​подробную информацию о пользовательских написанных исключениях, но большинство существующих исключений предоставляют намного больше, чем подробное сообщение и вызывающее исключение.

Например, вы можете обернуть все ваши потребности в разборе чисел в служебный класс, который перехватывает NumberFormatException и выдает вместо него пользовательское исключение (возможно, расширяющее NumberFormatException).

Примером, где некоторая дополнительная информация передается через исключение, является SQLException, который имеет getErrorCode() и getSQLState() метод.

3 голосов
/ 15 марта 2010

Создайте метод, такой как private parse (String value, int type), который выполняет фактическую работу синтаксического анализа, включая обработку исключений и ведение журнала.

 parse(ean, TYPE_LONG);
 parse(price, TYPE_BIG_DECIMAL);

Где TYPE_ - это просто что-то, что говорит методу, как он должен анализировать значение.

1 голос
/ 15 марта 2010

Подобно другому предложению, вы можете извлечь Long.parseLong(ean) в его собственный метод (либо в рамках класса, либо в открытом доступе для другого класса утилит).

Этот новый метод будет обрабатывать любую пользовательскую логику, и вы можете проверить ее изолированно. Yay!

...