У меня есть функция, что циклы при выполнении чего-то, что могло выдать исключение. Выглядит примерно так:
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;
}
Моя изначальная мысль (кроме того, что я этого не видел) заключается в том, что исключением является потенциально довольно большой объект (содержащий трассировку стека), и я бы предпочел , а не , чтобы хранить их много.
Вместо этого я бы построил список ошибочных параметров / аргументов по мере возникновения исключений и по завершении цикла выдал бы настраиваемое исключение, заполненное этим списком (если в списке больше 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);
}
}
На самом деле создание каких-либо исключений из такой функции, вероятно, не правильный способ справиться с этим, если ожидается, что будут ошибки. Я бы предложил либо вернуть список (массив) всех возникших исключений / ошибок, либо лучше предоставить объект обработчика ошибок функции, которая может обрабатывать исключения. то есть: [
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 );
}
}
}
] Это также позволяет обработчику ошибок либо собрать ошибки, чтобы представить их пользователю, либо решить, что вся пакетная операция стала недействительной из-за некоторой ошибки, и создать собственное исключение для преждевременного прерывания обработки.
Я думаю, вы можете передать метод обратного вызова или прослушивателя, или установить в переменной класса и вместо того, чтобы бросать список, как это сделал x4u.
В Java уже есть интерфейс для этого: java.beans.ExceptionListener
Откройте (и закройте!) тэги 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
и выдать его.
Если эти исключения действительно не связаны друг с другом, так что вы не можете воспользоваться функцией 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 обрабатывает именно такой подход более аккуратно. Вместо этого я бы выбрал :)
.Действительно ли вам нужно бросить все исключения? Как вы ожидаете обработки отдельных, не связанных с ними исключений? Как правило, в подобных случаях система просто сообщает об ошибках и выполняет их.
Если это так, можно просто собрать сообщения об ошибках и добавить их в пользовательский класс Exception
и выдать его.
Из руководства 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 ();
создает исключение из-за того, что вы не обработали предыдущее, может возникнуть нежелательная ошибка.
IMO, исключение должно быть последним ресурсом для обработки ошибки. По возможности этого следует избегать. Итак, вы можете захотеть передать описание ошибки (создать коды ошибок, передать сообщение или что-то значимое) в графический интерфейс, а не само исключение.