Лучшие практики для обработки ошибок Try Catch - PullRequest
4 голосов
/ 06 августа 2010

Я стараюсь не возвращать неправильное значение в улове, но у меня проблемы с поиском лучшего решения, чем это:

    private SecurityLevel ApiGetSecurityLevel()
    {
        try
        {
            return _BioidInstance.GetSecurityLevel();
        }
        catch
        { 
            return SecurityLevel.High;
        }
    }

Есть ли лучший способ сделать это, поэтому явернуть неправильные значения?Я не могу изменить перечисление SecurityLevel.

Ответы [ 11 ]

12 голосов
/ 06 августа 2010

Не поймать исключение. Разрешить исключению «всплывающее окно», чтобы заставить вызывающего абонента обрабатывать установку значения безопасности по умолчанию.


Если вы действительно хотите вернуть значение, используйте Nullable<SecurityLevel> или SecurityLevel?.

private SecurityLevel? ApiGetSecurityLevel() { 
    try { 
        return _BioidInstance.GetSecurityLevel(); 
    } 
    catch {  
        return null; 
    } 
} 

Тогда используйте как:

if (ApiGetSecurityLevel().HasValue == false) {
    // use default security level
}
6 голосов
/ 06 августа 2010

Возможно ли, что это тот случай, когда приложение должно просто выйти из строя?То есть, если SecurityLevel не может быть определен, пользователь не сможет продолжить?

Если это так, то почему бы просто не перезапустить и позволить обработать пользовательский интерфейс (или позволить ему войти в систему,однако ваш магазин работает)?

Если приложение сможет продолжить работу, выберите (и задокументируйте) какое-то значение по умолчанию и сделайте именно то, что вы делаете.

5 голосов
/ 06 августа 2010

Во-первых, нет причин для этого try / catch, если GetSecurityLevel возвращает SecurityLevel.Там компилятор обнаружит любые проблемы.

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

Если по какой-то причине GetSecurityLevel () не возвращает тип перечисления SecurityLevel:

private SecurityLevel ApiGetSecurityLevel()
    {
        object securityLevel = _BioidInstance.GetSecurityLevel();
        if (securityLevel is SecurityLevel)
        {
             return _BioidInstance.GetSecurityLevel();
        }
        else
        {
             throw new Exception("Invalid SecurityLevel");
        }
    }
2 голосов
/ 06 августа 2010

Если вы можете изменить тип возвращаемого значения, я заменю его на nullable enum и верну null в улове.

private SecurityLevel? ApiGetSecurityLevel()
{
    try
    {
        return _BioidInstance.GetSecurityLevel();
    }
    catch
    { 
        return null;
    }
}
1 голос
/ 06 августа 2010

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

1 голос
/ 06 августа 2010

Вы можете просто позволить исключению всплыть.

1 голос
/ 06 августа 2010

Вы можете ничего не вернуть.И сделайте так, чтобы ваша функция смотрела на результат, как будто NOT ApiGetSecurityLevel () - это ничто

0 голосов
/ 06 августа 2010

В этом случае безопасность становится двоичной.

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

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

Я бы полностью отказался от этого метода и заменил бы его на что-то ближе к

private bool HasSecurityLevel(SecurityLevel securityLevel) 
{ 
    try 
    { 
        return _BioidInstance.GetSecurityLevel() == securityLevel; 
    } 
    catch 
    {  
        return false; 
    } 
} 

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

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

0 голосов
/ 06 августа 2010
SecurityLevel sec = _BioidInstance.GetSecurityLevel();
return (Enum.IsDefined(Typeof(SecurityLevel), sec) ? sec : SecurityLevel.High);

Он вернет уровень безопасности в _BioidInstance, если он определен в перечислении, в противном случае он вернет SecurityLevel.High.

Если бы это был я, если бы я знал, что уровень безопасности не может быть ничем вне того, что определено в enum, я бы просто обошелся без try-catch и позволил бы ему потерпеть неудачу, если до него дойдет. Таким образом, я знаю, что где-то еще что-то пошло не так, и я могу исправить это.

0 голосов
/ 06 августа 2010

Если вы можете добавить перечисление Nothing / NotSet к SecurityLevel, вы можете вернуть его из блока catch.Возвращение расширенных привилегий, когда вы не можете определить их, является действительно странным выбором.

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

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