Как я могу поймать внутреннее исключение, которое присутствует только в сообщении родителя? - PullRequest
0 голосов
/ 05 июля 2018

Я пытаюсь перехватить исключение ORA-01013 в своем коде, но оно не отображается в правильном порядке в перехваченном исключении. У нас есть Trigger в базе данных, которая будет запускаться и регистрироваться каждый раз, когда SERVERRROR происходит в нашей базе данных Oracle. Это Trigger является причиной проблемы, но я не могу ее изменить.

Исключение не имеет InnerException, но исключение, которое я хочу перехватить, появляется в Message брошенного исключения.

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

Свойство Брошенного исключения .Message:

ORA-04088: error during execution of trigger 'TRIG_SERVER_ERRORS' // Don't want this
ORA-00604: error occurred at recursive SQL level 1
ORA-06502: PL/SQL: numeric or value error: character string buffer too small
ORA-06512: at line 14
ORA-01013: user requested cancel of current operation // Want this

Исключение, которое я хочу поймать, - ORA-01013, но выброшенное исключение - ORA-04088. Выданное исключение не имеет ссылки на требуемое исключение, кроме свойства .Message.

Пока я придумал это,

try
{
    ...
    ...
}
catch (OracleException ex)
{
    // if(ex.Number = 01013) // This doesn't work since ex.Number is 04088
    // if(ex.GetBaseException().Number) // Doesn't work also since ORA-04088 is the Base Exception
    if (ex.Message.Contains("ORA-01013")) // I want to catch this
    {
        throw new TimeoutException("The request took too long to complete. Please add more parameters to search by, or reduce the date duration", ex);
    }
    else
    {
        throw new DataAccessException(99999, ex, "ORA-{0} exception occurred during the inline call to {1}.", ex.Number.ToString(), MethedInfo.GetCurrentMethod().Name);
    }

Проблема с этим подходом состоит в том, что я вынужден обрабатывать любой OracleException, который входит в блок catch. Я мог бы добавить throw; в конце своего if или продолжить оборачивать выброшенные исключения в другом, но я бы предпочел только catch для определенного типа исключения , в котором есть текст сообщения, которым я являюсь после . Что я могу сделать?

1 Ответ

0 голосов
/ 05 июля 2018

C # 6 ввел ключевое слово когда для использования с блоком catch. Таким образом, вы можете указать выражение, чтобы сузить исключение, которое вы хотите перехватить, вместо этого фильтруя только по его типу и записывая логику if() внутри блока catch.

try
{
    ...
}
catch (OracleException ex) when (ex.Message.Contains("ORA-01013"))
{
    // do things with exception
}

Мне лично нравится это решение как:

  1. Намного легче просмотреть код и точно увидеть какого типа исключения, которое вы запрашиваете
  2. У вас нет корзины "catch all" со множеством операторов if или switch.
  3. Ваша ловушка очень сфокусирована на этом конкретном стиле, то есть вы можете объединить несколько из них в один try и упорядочить их по убыванию специфичности.

Что касается вашей ситуации с внутренними исключениями, не появляющимися - ну, вы с этим справились. Если разработчики библиотеки не дают вам истинного объекта InnerException для работы, вам не хватает проверки свойства строки Message.

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