Использование блока приложения для обработки исключений в корпоративной библиотеке в ASP.NET - обзор кода - PullRequest
2 голосов
/ 17 ноября 2009

Я реализую блок приложения для обработки исключений Enterprise Library в создаваемом мной приложении ASP.NET. Я планирую обработать необработанные исключения приложения, разместив следующий код в моем Global.asax.cs:

protected void Application_Error()
    {
        Exception error = Server.GetLastError();
        Exception errorToThrow;

        if (ExceptionPolicy.HandleException(error, "Application Error", out errorToThrow))
        {
            if (errorToThrow != null)
                throw errorToThrow;
        }
        else
            Server.ClearError();
    }

Я полагаю, что это будет работать для обработки различных действий политики после обработки (None, NotifyRethrow, ThrowNewException), но я хочу знать, видит ли кто-либо существенные проблемы с этой реализацией.

Ответы [ 3 ]

5 голосов
/ 18 ноября 2009

Я вижу несколько проблем:

  • Возможно, вы захотите обработать HttpUnhandledException в вашем обработчике ошибок. Это то, чем будет большинство исключений, поднятых вашей страницей.

  • Я не вижу значения политики дескриптора и возобновления (PostHandlingAction = None), в которой вы вызываете Server.ClearError (). По сути, ваша страница вызвала исключение, и вы ничего не делаете. В лучшем случае пользователь видит пустую страницу. В худшем случае, вы можете получить частично обработанную страницу без указания того, что произошло.

  • Я также не вижу смысла потенциально вызывать исключение из вашего обработчика ошибок. Вы либо получите желтый экран смерти, либо заставите вызвать другую страницу с ошибкой (например, перенаправление customErrors, определенное в web.config).

  • Ваша логика HandleException не учитывает сценарий NotifyRethrow. (удалено на основании комментария, что существует перенаправление customError) .

Использование @ vladhorby's ErrorPage и сохранение вашей основной логики даст что-то вроде этого:

protected void Application_Error()
{
    Exception error = Server.GetLastError();

    if (error is HttpUnhandledException)
    {
        error = error.InnerException;
    }

    Exception errorToThrow;

    if (ExceptionPolicy.HandleException(error, "Application Error", out errorToThrow))
    {
        Response.Redirect(string.Format("ErrorPage.aspx?Message={0}", Uri.EscapeDataString((errorToThrow ?? error).Message)));   
    }
    else
    {
        Server.ClearError();
    }
}


Несколько замечаний по поводу приведенного выше кода:

  • Если ErrorPage.aspx по какой-то причине выдает исключение, вы можете оказаться в бесконечном цикле, поэтому убедитесь, что ErrorPage.aspx имеет собственный Page_Error, чтобы попытаться избежать необработанных исключений, распространяющихся на глобальный обработчик ошибок.

  • Не принимаются во внимание возражения 2 и 3.:)

Я не уверен в вашей ситуации и требованиях, но вы рассматривали возможность использования ELMAH ?

0 голосов
/ 23 февраля 2010

Для тех, кто заинтересован, я обновил свой код, основываясь на некоторых проблемах, которые у меня были. В частности, я хотел, чтобы пользователи видели страницу с ошибкой, но не изменили свой URL, поэтому я не мог полагаться на пользовательскую обработку ошибок web.config. Я обнаружил, что этот метод дает мне больше контроля над обработкой ошибок.

if (this.Context.IsCustomErrorEnabled)
{
    Exception originalError = Server.GetLastError();
    Exception replacedError;

    if (ExceptionPolicy.HandleException(originalError, "Application Error", out replacedError))
    {
        if (replacedError != null)
            this.Context.Items[ErrorController.ExceptionKey] = replacedError;
        else
            this.Context.Items[ErrorController.ExceptionKey] = originalError;

        Server.ClearError();

        // Perform an MVC "Server.Transfer" to the error page.
        this.Context.RewritePath(DefaultRedirectUrl);

        IHttpHandler handler = new MvcHttpHandler();
        handler.ProcessRequest(this.Context);
    }
}

Некоторые замечания об этой реализации:

  1. «DefaultRedirectUrl» - это свойство, которое извлекает URL-адрес перенаправления ошибок по умолчанию из файла web.config, который представляется наиболее логичным местом для хранения этой информации.
  2. Я использую методологию MVC "Server.Transfer" из этого вопроса на SO.
  3. Перенаправление по умолчанию - это действие на ErrorController, которое извлекает ошибку из HttpContext и обрабатывает ее соответствующим образом.
0 голосов
/ 18 ноября 2009

Выглядит хорошо, но вы можете перенаправить на страницу с ошибкой, а не перебрасывать (это удобнее для пользователя):

Exception wrappedEx;
ExceptionHandlerHelper.ExceptionHandler.HandleException(ex, "MyPolicy", out wrappedEx);
Response.Redirect(string.Format("ErrorPage.aspx?Message={0}", Uri.EscapeDataString((wrappedEx ?? ex).Message)));
...