2009-08-05 2 views
2

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

Public Sub StartService() 
    RunSearch() 
    SaveMessages() 
    DeleteMessages() 
End Sub 

внутри каждого из методов RunSearch(), SaveMessages() and DeleteMessages() я использую заявления Try поймать поймать ошибки. Прямо сейчас я поймаю ошибку и напишу в журнал ошибок, когда ошибки RunSearch(), но я также получаю две ошибки от SaveMessages() и DeleteMessages(), потому что эти функции зависят от RunSearch(), не возвращая ошибки. Я пытаюсь создать хорошую ошибку, поймав фундамент, поэтому я не просто хочу убить приложение, когда есть ошибка. Мой вопрос заключается в следующем: как я могу изящно остановить выполнение, если ошибка возникает в RunSearch().

ответ

5

Почему RunSearch не исключение повторно выдать после регистрации проблемы?

Если вы не хотите звонить SaveMessages(), если RunSearch() не работает, тогда не указывайте его таким образом.

Моя общая мысль заключается в том, что интерфейс каждого метода указывает «протокол». Он должен указать свое поведение в случае проблем. Подходы включают:

  1. Если у меня возникла ошибка, я закончу процесс. Это довольно экстремально, ограничивает возможность повторного использования вашего метода.
  2. Я верну счет или код состояния или somesuch. Вам решать, проверять ли это, и означает ли какой-либо конкретный код состояния, можно безопасно вызвать какой-либо другой метод. Я предпочитаю не полагаться на клиента, чтобы не забывать проверять коды состояния.
  3. Если я потерплю неудачу, я оставлю вещи, чтобы последующая обработка была разумной. Например, если моя задача - создать связанный список, тогда в случае ошибок я не оставлю оборванный указатель или инициализированный список. Вы можете получить пустой список, но по крайней мере хорошо сформированная последующая обработка будет работать. Это имеет тенденцию подразумевать некоторую степень согласия (т. Е. Связь) с другими методами. Это часто самый приятный подход, особенно в сочетании с хорошим протоколированием проблем.
  4. Я сделаю исключение, если не смогу выполнить эту работу. Исключение укажет, есть ли вероятность того, что работа будет работать позже, если вы снова вызовете (я довольно часто использую TransientException и InvalidRequestException). Исключения полезны, потому что клиент не может (для проверенных исключений Java) случайно их игнорировать. При решении таких проблем, как «невозможно открыть базу данных», это кажется разумным. Мы действительно не хотим, чтобы люди ошибались, «даже не могли попасть в базу данных», «у этого человека нет судимости».
+0

Другое хорошее предложение. Thumbs up и upvote для вас и @Rob Thijssen. – David

+0

Ahh. Этот ответ касается DESIGN. настолько соблазнительно погрузиться в написание кода, но он уверен, что сначала поможет подумать (и задокументировать ответы). – Bill

3

Одним из возможных вариантов было бы изменить метод RunSearch, чтобы вернуть Boolean - True в случае успеха и False, если произошла ошибка, которая блокировала бы две другие функции.

Тогда вы могли бы сделать это:

Public Sub StartService() 
    If RunSearch() Then 
     SaveMessages() 
     DeleteMessages() 
    End If 
End Sub 
1

Вы можете повторно удалить исключения метода после того, как выполнили регистрацию, а затем заверните свой метод RunSearch() внутри блока try/catch, чтобы следующие два метода не выполнялись.

1

Кажется, что вам не нужны низкоуровневые обработчики ошибок на уровне метода, но только обработчик высокого уровня/уровня приложения. Если все блоки catch для каждого метода одинаковы, я бы предложил переключиться на высокоуровневый обработчик ошибок.Как правило, вы только хотите поймать Исключения, которые вы можете явно обработать, или поймать их при последней oppurtunity для целей ведения журнала и предотвратить untidy crashses приложения.

Это, как я хотел бы подойти к нему

public void StartService() 
{ 
    try 
    { 
     RunSearch(); 
     SaveMessages(); 
     DeleteMessages(); 
    } 
    catch(Exception ex) 
    { 
     //Do Nothing or Log ex 
    } 
} 

public void RunSearch() 
{ 
//No error handler here, as this method cannot recover from exceptions 

//RunSearch functionality 
} 
+0

Если вы отступаете от кода 4 пробела, мы получим подсветку синтаксиса ... – grenade

+0

Не обижайтесь матом, но если вопрос находится в VB от допущенного новичка, я рекомендую ответить в VB. – Bill

+0

@Rob. Спасибо, забыли отформатировать его @Bill. Точка поняла, но OP отметил вопрос C#, так что предположил, что все в порядке – MattH

0

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

Ответ Дэвида Стреттона выше - это гораздо лучшее решение.

Смежные вопросы