Мой C# 6, .Net 4.6, Entity Framework 6 Приложение имеет множество методов по этой базовой схеме:Устранить дублирование кода в C# уловом
try
{
using (Entities dbContext = new Entities())
{
// Some database stuff
}
}
catch (System.Data.Entity.Core.EntityException eEntCore)
{
// May occur if connection to DB fails
throw MyApplicationException("Cannot access data store (Entity Core Exception)", eEntCore);
}
catch (System.Data.Entity.Infrastructure.DbUpdateException eDbu)
{
throw MyApplicationException("Cannot access data store (Database Exception)", eDbu);
}
catch (System.Data.SqlClient.SqlException eSql)
{
// Usually occurs after a Referential Integrity error
throw MyApplicationException("Cannot access data store (Data Exception)", eSql);
}
Эти исключения являются те, которые я обнаружил до сих пор - там может больше.
Моя проблема заключается в том, что если появляется другой тип исключения, мне нужно внести поправки в десятки методов, чтобы добавить новое исключение. Я попытался централизовать обработку ошибок с помощью этого блока catch:
catch (Exception e)
{
AnalyseException(e);
}
где AnalyseException() выполняет работу; он выдает либо исключение MyApplicationException, либо исходное (неизвестное) исключение. Конструктивные работы, за исключением того, что трассировка стека не сохраняется (и она совершает серьезный грех при исключении исключения).
Интерфейс пользователя обрабатывает исключение MyApplicationException. Я не хочу, чтобы он обрабатывал все типы исключений EF и SQL.
Я попытался переработать дизайн с помощью этой функции C# 6:
catch (Exception ex) when (AnalyseException(ex))
, но я не могу получить, чтобы сохранить трассировку стека. Есть ли способ сохранить трассировку стека без большого количества дублированного кода?
Почему вы вообще ловите исключения? Это похоже на фатальный недостаток. –
Я считаю, что это связано с поведением стека и исключениями. Прочтите раздел «Примечания» на этой странице (https://msdn.microsoft.com/en-us/library/system.exception.stacktrace(v=vs.110).aspx). «Если исключение выбрано, а затем повторно показано, в том же методе, трассировка стека содержит только место, где исключение было восстановлено, и не включает в себя местоположение, в котором исключение было изначально выбрано». – wentimo
Хотя я полностью согласен с ответами Криса и Даниэля, существует огромная разница между 'throw ex'' и' throw; 'insider 'catch'. Первый удаляет трассировку стека. Последний перебрасывает пойманное исключение и сохраняет трассировку стека. Кроме того, вы создаете новые экземпляры исключений и включаете исключение catch в качестве внутреннего исключения. Это внутреннее исключение будет включать исходную трассировку стека. –