Повторное генерирование исключения в C #

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

catch ( Exception exSys )   {
    bqBusinessQuery.RollBackTransaction();
    throw exSys ;
}

Если я использую этот код, анализ VS Code выдает предупреждение:

Вместо этого используйте 'throw' без аргумента, чтобы сохранить место стека, в котором изначально было вызвано исключение.

Если я использую код

catch ( Exception exSys )   {
    bqBusinessQuery.RollBackTransaction();
    throw;
}

тогда я получаю предупреждение

Переменная exSys объявлена, но никогда не используется

Как мне решить эту проблему?

Изменить. Я пробовал этот метод, но он не работает. Класс system.exception требует дополнительного сообщения вместе с внутренним исключением. Если я это сделаю, он выдаст новое сообщение, переопределяющее сообщение из исходного исключения. Я не хочу получать новое исключение, я хочу выбросить то же исключение с тем же сообщением.

    catch (System.Exception ex)
    {
        throw new System.Exception(ex);
    }

Изменить

        catch (System.Exception ex)
        {
            throw new System.Exception("Test",ex);
        }

Пробовал этот способ. А затем вручную вызвал исключение с помощью throw new Exception("From inside");. Теперь ex.Message возвращает «Test» вместо «From inside». Я хочу оставить это сообщение «Изнутри» как есть. Это предлагаемое изменение вызовет проблемы с отображением кода ошибки повсюду. : /


person jitendragarg    schedule 11.05.2016    source источник
comment
используйте 1_   -  person Nino    schedule 11.05.2016
comment
@nino .. throw exSys обычно не одобряется, поскольку он создает за собой новый стек, а throw - нет. однако это означает, что вы получили это предупреждение - хотя, поскольку исключение не используется напрямую, вы, вероятно, могли бы просто выполнить catch {..; throw}, но не пробовал   -  person BugFinder    schedule 11.05.2016
comment
Если вы не хотите использовать исключение, нет смысла его ловить.   -  person Marco    schedule 11.05.2016
comment
@Nino правда, не делайте это.   -  person Charles Mager    schedule 11.05.2016
comment
@Fabjan: в предложенном дублированном принятом ответе используется catch (Exception exSys) { throw;}, чего OP хочет избежать. Итак, этот вопрос касается неиспользуемой переменной исключения, а не _2 _ / _ 3_.   -  person Tim Schmelter    schedule 11.05.2016
comment
@Charles спасибо за предложения.   -  person Nino    schedule 11.05.2016
comment
@TimSchmelter Более-менее, да. Мне кажется, что я могу либо сохранить трассировку стека, либо оставить предупреждение без предупреждения. Я даже не могу создать новое исключение, потому что тогда строка ex.Message не вернет фактическую ошибку.   -  person jitendragarg    schedule 11.05.2016
comment
Вы продолжаете задавать новые вопросы, на которые у вас уже есть ответы.   -  person Martin Prikryl    schedule 11.05.2016
comment
@MartinPrikryl Извини, я тебя не понимаю. Нет нового вопроса. Есть только правки, основанные на том, что было предложено здесь в качестве ответа. Если ни один из методов, которые я пробовал, не сработал, я добавлю эту деталь в вопрос.   -  person jitendragarg    schedule 11.05.2016
comment
Если вы хотите сохранить сообщение об ошибке и стек, используйте только throw. Почему вы продолжаете пробовать другие методы?   -  person Martin Prikryl    schedule 11.05.2016
comment
потому что тогда я ничего не могу сделать в этом блоке catch. Я хочу создать журнал или отправить электронное письмо на основе сообщения, а затем передать исключение вызывающей функции. Если я не объявлю переменную, logText += ex.Message или аналогичная строка работать не будут. И на самом деле я нормально могу выбросить трассировку стека, если VS меня по этому поводу не беспокоит.   -  person jitendragarg    schedule 11.05.2016
comment
Но вы никогда не говорили нам, что хотите использовать исключение в блоке catch! См. Мой отредактированный ответ.   -  person Martin Prikryl    schedule 11.05.2016


Ответы (2)


Вам не нужно привязывать переменную к исключению:

try
{
    ...
}
catch (Exception) 
{
    bqBusinessQuery.RollBackTransaction();
    throw;
}

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

try
{
    ...
}
catch
{
    bqBusinessQuery.RollBackTransaction();
    throw;
}

Или (как предлагается @Zohar Peled) генерировать новое исключение, используя перехваченное исключение в качестве внутреннего исключения. Таким образом вы сохраните стек и придадите исключению больше контекста.

try
{
    ...
}
catch (Exception e)
{
    throw new Exception("Transaction failed", e);
}

Если вы действительно хотите использовать исключение для некоторой обработки (например, зарегистрировать его), но хотите повторно выбросить его без изменений, объявите переменную, но используйте простой throw:

try
{
    ...
}
catch (Exception e)
{
    Console.WriteLine(e.Message);
    throw;
}
person Martin Prikryl    schedule 11.05.2016
comment
другой вариант: выброс нового исключения с исходным исключением как внутреннее исключение: catch(Exception ex) { throw new Exception(ex)} - person Zohar Peled; 11.05.2016
comment
@ZoharPeled Спасибо. Добавлен. - person Martin Prikryl; 11.05.2016
comment
Используя третий вариант, потому что я хочу сохранить внутреннее сообщение об исключении, но не иметь дело с предупреждениями. :) - person jitendragarg; 11.05.2016
comment
Что ж, вы получите все, что будет во всех трех вариантах. - person Martin Prikryl; 11.05.2016
comment
Если вы хотите создать такое же исключение, используйте только throw (первые два параметра). - person Martin Prikryl; 11.05.2016
comment
Вот с чего я начал. Но этот выдает предупреждение, когда e.Message нигде не используется. Думаю, я сделаю это двумя способами. Когда мне нужно использовать исключение, я объявлю переменную, в противном случае я оставлю ее пустой. Бросьте, я сохраню ясность. :) - person jitendragarg; 11.05.2016
comment
Вот как это сделать. Если вам нужна переменная, объявите ее, если нет - не надо. - person Martin Prikryl; 11.05.2016
comment
Измените вопрос, чтобы было ясно, что вы хотите использовать переменную. Значит, это не дубликат. - person Martin Prikryl; 11.05.2016

catch (Exception)   
{
    bqBusinessQuery.RollBackTransaction();
    throw;
}

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

person Kyle Muir    schedule 11.05.2016
comment
В некоторых случаях мы передаем сообщение. Например, если проверка запроса завершается неудачно, в приложении часто встречается throw new Exception("custom message");. Затем то же самое передается внешней вызывающей функции, которая обновляет пользовательский интерфейс для отображения ошибки. - person jitendragarg; 11.05.2016
comment
В этом случае вам следует throw new exception("custom message", originalException), чтобы не потерять трассировку стека. - person Kyle Muir; 11.05.2016
comment
за великолепное использование розового вы получите +1 - person MickyD; 11.05.2016
comment
@KyleMuir Могу я сделать throw new exception(originalException). Я не пытаюсь добавить новое сообщение, просто сохраняю исходное сообщение, которое было при первом возникновении исключения. Например. execute query функция выдает исключение, говоря primary key already exists, тогда я просто хочу откатить транзакцию и пропустить то же сообщение об исключении. - person jitendragarg; 11.05.2016
comment
@jitendragarg Ага, ничего плохого в этом нет. Мы часто перехватываем общие исключения и заключаем их в свои собственные, чтобы мы могли их отловить и разобраться с ними. Например. настраиваемое исключение DatabaseException или что-то еще. - person Kyle Muir; 11.05.2016
comment
Здорово. Спасибо. Тогда это должно сработать. :) - person jitendragarg; 11.05.2016
comment
Подожди, теперь у меня новая проблема. `catch (System.Exception ex) {выбросить новое System.Exception (ex); }' не работает. Это дает мне ошибку, говоря, что лучший перегруженный метод имеет недопустимый аргумент. Требуется сообщение об ошибке. - person jitendragarg; 11.05.2016
comment
@jitendragarg Вы совершенно правы. Извините, уже поздно, и я устал. catch (Exception ex) { throw new Exception("Database Exception", ex); } или подобное должно работать нормально :) - person Kyle Muir; 11.05.2016
comment
Это вызывает другую проблему. Проверьте редактирование вопроса. - person jitendragarg; 11.05.2016
comment
А как насчет: catch (Exception ex) { throw new Exception(ex.Message, ex); }, однако, пища для размышлений: если вы создаете новое исключение со всей той же информацией, что и исходное, - зачем вы это делаете? - person Kyle Muir; 11.05.2016
comment
Давайте продолжим это обсуждение в чате. - person jitendragarg; 11.05.2016