Это плохая практика возвращать исключения из ваших методов - PullRequest
12 голосов
/ 10 июня 2009

Множество методов кода, написанных моими коллегами, выполняют свою собственную обработку ошибок, обычно путем перехвата, уведомления и ведения журнала.

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

Иногда, если метод дает сбой, я хочу, чтобы вызывающий код знал, почему, и возврата логического значения недостаточно.

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

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

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

Например, если метод просто void, может быть не сразу очевидно, что программист должен обработать успех или неудачу.

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

Имеет ли это смысл? Может быть, я не использовал лучший пример, , но в целом нормально возвращать исключения или существует лучший шаблон?

UPDATE

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

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

UPDATE:

Я действительно ценю все мнения, я читаю все и тщательно обдумываю все входные данные.

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

Ответы [ 16 ]

1 голос
/ 10 июня 2009

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

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

1 голос
/ 10 июня 2009

Нет, я не считаю это хорошей практикой.

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

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

Вы всегда можете избавить своих клиентов от необходимости писать блоки try / catch, выбрасывая непроверенные исключения.

1 голос
/ 10 июня 2009

Я никогда не видел метод, который возвращает исключение. Обычно метод возвращает значение, и этот метод может выбросить исключение. Но я никогда не видел код с возвратом нового System.InvalidOperationException («Файл журнала не может быть доступен только для чтения»); например ...

Итак, чтобы ответить на ваш вопрос, я бы сказал, да, это плохо ...

0 голосов
/ 22 августа 2013

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

static public ErrorException ReturnErrAsExcep()
{
    int errcd = 0;
    string errmsg = "";

    CrummyComLib.GetLastError(out errcd, out errmsg);
    ErrorException ex = new SAPErrorException(errmsg, errcd);
    return ex;
} 

Который я бы использовал как

int retval = CrummyComObject.DoStuff();

if (retval != 0)
    throw globals.ReturnErrAsExcep();
0 голосов
/ 30 августа 2011

Я часто возвращаю исключение, используя этот шаблон, чтобы избежать нескольких блоков try {} catch, которые запутывают код, поэтому я бы сказал, что в некоторых случаях рекомендуется возвращать исключение.

public void Method(string text)
{
   //throw exception if needed
   throw new Exception("exception"); 
}

public bool TryMethod(string text, out Exception ex)
{
   try
   {
      Method("test")
      ex = null;
      return true;
   }
   catch(Exception e)
   {
      ex = e;
      return false;
   }
}
0 голосов
/ 10 июня 2009

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

...