Бросок связанного списка исключений в Java

У меня есть функция, что циклы при выполнении чего-то, что могло выдать исключение. Выглядит примерно так:

public void myFunction() throws MyException {
    while(stuff) {
        try {
            DoSomething() // throws an exception
        }
        catch (Exception ex) {
            throw new MyException(some, stuff, of, mine, ex);
        }
    }
}

Ошибка при порождении исключения исправима. Это может быть что-то как ошибка SQL в единственном операторе обновления, где цикл с условием продолжения выполняет серию операторов обновления. Или ошибка анализа в единственной части данных, где цикл обрабатывает несколько частей данных. Я должен передать исключение далее цепочка, таким образом, часть GUI программы может обработать его, обработать его и передать ошибку пользователю. Но я не хочу уничтожать цикл в этой конкретной функции. Другие вещи, которые это делает, не могли бы быть недопустимыми. Ошибка, которая вызвала исключение, не могла бы быть фатальной для функции.

Таким образом, мой вопрос - это: действительно ли это - приемлемая практика для создания связанных списков пользовательских исключений (где каждым исключением является узел, и выданным исключением является заголовок списка), и затем бросьте заголовок списка (если таковые имеются), как только цикл заканчивается?

Кто-либо когда-либо видел сделанный? Кто-либо может думать о каких-либо потенциальных проблемах с выполнением этого? Может любой думать о другом, лучшие способы решить корневую проблему: потребность отказаться от нескольких несвязанных исключений с выходом из функции, пока это не сделано?

Вот пример того, как соединение и бросок могли бы быть реализованы очень просто:

public void myFunction() throws MyException {
    MyException head = null;
    while(stuff) {
        try {
            DoSomething() // throws an exception
        }
        catch (Exception ex) {
            MyException tmp = new MyException(some, stuff, of, mine, ex);
            tmp.next(head);
            head = tmp;
        }
    }
    if(head != null)
       throw head;
}
17
задан Daniel Bingham 4 February 2010 в 20:46
поделиться

7 ответов

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

Вместо этого я бы построил список ошибочных параметров / аргументов по мере возникновения исключений и по завершении цикла выдал бы настраиваемое исключение, заполненное этим списком (если в списке больше 0 элементов). Казалось бы, это более управляемый способ справиться с этим сценарием.

public void myFunction() throws CustomException {
    List<MyError> errors = new ArrayList<MyError>();
    while(stuff) {
        try {
            DoSomething() // throws an exception
        }
        catch (Exception ex) {
            errors.add(new MyError(some, stuff, of, mine, ex));
        }
    }
    if (errors.size() > 0) {
       throw new CustomException(errors);
    }
}
16
ответ дан 30 November 2019 в 13:05
поделиться

На самом деле создание каких-либо исключений из такой функции, вероятно, не правильный способ справиться с этим, если ожидается, что будут ошибки. Я бы предложил либо вернуть список (массив) всех возникших исключений / ошибок, либо лучше предоставить объект обработчика ошибок функции, которая может обрабатывать исключения. то есть: [

public interface ErrorHandler
{
    public void handleError( Throwable ex /*, add some context info */ );
}

public void myFunction( ErrorHandler eh )
{   
    while(stuff) {   
        try {   
            DoSomething() // throws an exception   
        }   
        catch (Exception ex) {
            if( eh != null )
                eh.handleError( ex );
        }   
    }   
}   

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

2
ответ дан 30 November 2019 в 13:05
поделиться

Я думаю, вы можете передать метод обратного вызова или прослушивателя, или установить в переменной класса и вместо того, чтобы бросать список, как это сделал x4u.

В Java уже есть интерфейс для этого: java.beans.ExceptionListener

1
ответ дан 30 November 2019 в 13:05
поделиться

Откройте (и закройте!) тэги PHP сразу после textarea тэгов:

<textarea style="width:350px; height:80px;" cols="42" rows="5" name="sitelink"><?php
  if($siteLink_val) echo $siteLink_val;
?></textarea>
-121--576942-

PHP не поддерживает явную типизацию членов класса. Так что вы не можете сказать:

public Object $objectname;

Если класс Object существует, и вы хотите его экземпляр, попробуйте:

 public $objectname = new Object();
-121--2323122-

Действительно ли вам нужно бросить все исключения? Как вы ожидаете обработки отдельных, не связанных с ними исключений? Как правило, в подобных случаях система просто сообщает об ошибках и выполняет их.

Если это так, можно просто собрать сообщения об ошибках и добавить их в пользовательский класс Exception и выдать его.

3
ответ дан 30 November 2019 в 13:05
поделиться

Если эти исключения действительно не связаны друг с другом, так что вы не можете воспользоваться функцией get/setCause(), то я бы предпочел собрать эту информацию в одном MyException.

Например,

public void myFunction() throws MyException {
    MyException myException = null;
    while(stuff) {
        try {
            DoSomething() // throws an exception
        }
        catch (Exception ex) {
            if (myException == null) {
                myException = new MyException();
            }
            myException.addException(some, stuff, of, mine, ex);
        }
    }
    if (myException != null) {
        throw myException;
    }
}

Update: Brian обрабатывает именно такой подход более аккуратно. Вместо этого я бы выбрал :)

.
3
ответ дан 30 November 2019 в 13:05
поделиться

Действительно ли вам нужно бросить все исключения? Как вы ожидаете обработки отдельных, не связанных с ними исключений? Как правило, в подобных случаях система просто сообщает об ошибках и выполняет их.

Если это так, можно просто собрать сообщения об ошибках и добавить их в пользовательский класс Exception и выдать его.

-121--1672049-

Из руководства PHP по свойствам класса (акцент мой):

Переменные-члены класса называются «свойствами». Вы также можете видеть их с использованием других терминов, таких как «атрибуты» или «поля», но для целей этой ссылки мы будем использовать «свойства». Они определяются с помощью одного из ключевых слов public, protected или private с последующим обычным объявлением переменной. Это объявление может включать в себя инициализацию, но эта инициализация должна быть постоянным значением --то есть она должна быть в состоянии быть оценена во время компиляции и не должна зависеть от информации времени выполнения, чтобы быть оцененной.

Создайте его внутри конструктора ( композиция )

class Foo
{
    protected $bar;
    public function __construct()
    {
        $this->bar = new Bar;   
    }
}

или введите в конструктор ( агрегация )

class Foo
{
    protected $bar;
    public function __construct(Bar $bar)
    {
        $this->bar = $bar;   
    }
}

или используйте инъекцию установщика.

class Foo
{
    protected $bar;
    public function setBar(Bar $bar)
    {
        $this->bar = $bar
    }
}

Вы хотите отдавать предпочтение агрегации по сравнению с композицией .

-121--2323120-

Если исключение, созданное DoSomething (); , может привести к тому, что тот же самый метод вызовет еще одно исключение; это может быть проблемой. Другими словами, если DoSomething (); создает исключение из-за того, что вы не обработали предыдущее, может возникнуть нежелательная ошибка.

1
ответ дан 30 November 2019 в 13:05
поделиться

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

0
ответ дан 30 November 2019 в 13:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: