Ошибки журнала, обработанные в try..catch с Elmah
Я пытаюсь войти в систему с исключениями Elmah, обрабатываемыми в блоках try...catch
.
Я добавил глобальный фильтр ошибок обработчика на Global.axax
:
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new ElmahHandledErrorLoggerFilter());
filters.Add(new HandleErrorAttribute());
}
Это мой ElmahHandledErrorLoggerFilter
:
public class ElmahHandledErrorLoggerFilter : IExceptionFilter
{
public void OnException(ExceptionContext context)
{
if (context.ExceptionHandled)
ErrorSignal.FromCurrentContext().Raise(context.Exception);
}
}
Он будет записывать только Исключение, как в try{ ... }catch{ throw new Exception(); }
. Но это не проблема, проблема в том, что у меня есть метод с try-catch, вызванный из кода уже внутри другого try-catch. В этом случае, хотя я положил throw new Exception()
внутри catch внутреннего метода, он не регистрирует исключение, он возвращается к catch в первом методе без регистрации Исключения. Например:
public void MainMethod()
{
try
{
SecondMethod();
}
catch
{
....second method jump here.....
}
}
public void SecondMethod()
{
try
{
int a =0;
int b =;
int result = b/a;
}
catch
{
throw new Exception();
}
}
Исключение, созданное SecondMethod
, не регистрируется Elmah. Он возвращается к основному методу catch. Если основной метод catch также имеет код throw new Exception()
, тогда он регистрирует исключение. Однако он будет регистрироваться с трассировкой стека, указывающей на MainMethod
, а не на SecondMethod
.
То, что я хотел, чтобы каждый раз, когда он достиг уловки, не пересоздавая новое исключение, Elmah регистрировал бы исключение. Это связано с тем, что у меня есть много блоков try-catch в моем приложении, и я хочу регистрировать эти исключения без ручного входа в каждый try-catch. Однако, если вы скажете мне, как я могу зарегистрировать исключение из SecondMethod
, это будет нормально.
Ответы
Ответ 1
Используете ли вы ASP MVC?
Фильтры будут выполняться только для необработанных исключений, исходящих из методов контроллера. (Свойство context.ExceptionHandled
указывает вам, был ли он обработан другим фильтром, а не блоком try-catch). Поэтому, если вы проглотите исключения в блоках try-catch внутри своих методов, они не будут обрабатываться фильтрами ошибок.
Вам нужно решить, когда вы хотите вручную обрабатывать исключения внутри вашего кода, используя блоки try-catch (и в этом случае вручную регистрировать исключения с помощью базового класса контроллера или вспомогательного класса) или позволить пузырю исключения и обрабатывать ваши фильтры. (Вероятно, вам понадобится смесь двух, в зависимости от каждого конкретного варианта использования)
Когда вы решите перебросить исключения, посмотрите этот вопрос SO. В основном вы можете перестроить исключение, сохраняя трассировку стека с помощью:
try
{
//code
}
catch (Exception ex)
{
//...some error handling code here...
//Otherwise why the try-catch at all?
throw;
}
Вы можете сделать это в своем примере MainMethod
, и журнал регистрации будет сохранять трассировку стека.