Обработка необработанных исключений (VB)
Просмотреть или скачать образец кода (как скачивать)
При возникновении ошибки среды выполнения в веб-приложении в рабочей среде важно уведомить разработчика и записать ее в журнал, чтобы ее можно было диагностировать позже. В этом руководстве представлен обзор того, как ASP.NET обрабатывает ошибки среды выполнения, и рассматривается один из способов выполнения пользовательского кода при каждом необработанных исключениях до среды выполнения ASP.NET.
Введение
При возникновении необработанного исключения в ASP.NET приложении оно выполняется в ASP.NET среде выполнения, которая вызывает Error
событие и отображает соответствующую страницу ошибки. Существует три различных типа страниц ошибок: желтый экран смерти ошибки времени выполнения (YSOD); сведения об исключении YSOD; и пользовательские страницы ошибок. В предыдущем руководстве мы настроили приложение для использования настраиваемой страницы ошибок для удаленных пользователей и YSOD сведений об исключении для пользователей, посещающих локально.
Использование удобной для пользователя пользовательской страницы ошибок, которая соответствует интерфейсу сайта, предпочтительнее, чем YSOD ошибки среды выполнения по умолчанию, но отображение настраиваемой страницы ошибок является лишь одной из частей комплексного решения для обработки ошибок. При возникновении ошибки в приложении в рабочей среде важно, чтобы разработчики были уведомлены об этой ошибке, чтобы они могли узнать причину исключения и устранить ее. Кроме того, сведения об ошибке должны быть записаны в журнал, чтобы ее можно было проверить и диагностировать позже.
В этом руководстве показано, как получить доступ к сведениям о необработанных исключениях, чтобы их можно было заносить в журнал и уведомлять разработчика. В двух следующих руководствах рассматриваются библиотеки ведения журнала ошибок, которые после некоторой настройки автоматически уведомляют разработчиков об ошибках среды выполнения и регистрируют их сведения.
Примечание
Сведения, рассмотренные в этом руководстве, наиболее полезны, если вам нужно обрабатывать необработанных исключений каким-то уникальным или настраиваемым способом. В тех случаях, когда необходимо только записать исключение и уведомить разработчика, следует использовать библиотеку ведения журнала ошибок. В следующих двух учебниках представлен обзор двух таких библиотек.
Выполнение кода при возникновенииError
события
События предоставляют объекту механизм для сигнализации о том, что произошло что-то интересное, и для другого объекта для выполнения кода в ответ. Как разработчик ASP.NET вы привыкли думать с точки зрения событий. Если вы хотите запустить код, когда посетитель нажимает определенную кнопку, создайте обработчик событий для события этой кнопки Click
и поместите в нее свой код. Учитывая, что среда выполнения ASP.NET вызывает свое Error
событие всякий раз, когда возникает необработанное исключение, код для ведения журнала сведений об ошибке будет идти в обработчике событий. Но как создать обработчик событий для Error
события?
Событие Error
является одним из многих событий в HttpApplication
классе , которые вызываются на определенных этапах конвейера HTTP в течение времени существования запроса. Например, HttpApplication
событие класса BeginRequest
возникает в начале каждого запроса; его AuthenticateRequest
событие возникает, когда модуль безопасности идентифицирует инициатор запроса. Эти HttpApplication
события предоставляют разработчику страницы средства для выполнения пользовательской логики в различные моменты времени существования запроса.
Обработчики HttpApplication
событий можно поместить в специальный файл с именем Global.asax
. Чтобы создать этот файл на веб-сайте, добавьте новый элемент в корень веб-сайта с помощью шаблона Global Application Class с именем Global.asax
.
Рис. 1. Добавление Global.asax
в веб-приложение
(Щелкните для просмотра полноразмерного изображения)
Содержимое и структура файла, Global.asax
созданного Visual Studio, немного различаются в зависимости от того, используете ли вы проект веб-приложения (WAP) или проект веб-сайта (WSP). При использовании WAP Global.asax
реализуется как два отдельных файла : Global.asax
и Global.asax.vb
. Файл Global.asax
не содержит ничего, @Application
кроме директивы, которая ссылается на .vb
файл; обработчики событий, представляющие интерес, определяются в Global.asax.vb
файле . Для WSP создается только один файл , Global.asax
а обработчики событий определяются в блоке <script runat="server">
.
Файл Global.asax
, созданный в WAP шаблоном глобального класса приложения Visual Studio, включает обработчики событий с именами Application_BeginRequest
, Application_AuthenticateRequest
и Application_Error
, которые являются обработчиками HttpApplication
событий BeginRequest
, AuthenticateRequest
и Error
соответственно. Существуют также обработчики событий с именами Application_Start
, Session_Start
, Application_End
и Session_End
, которые являются обработчиками событий, которые срабатся при запуске веб-приложения, при запуске нового сеанса, при завершении приложения и при завершении сеанса соответственно. Файл Global.asax
, созданный в WSP Visual Studio, содержит только обработчики Application_Error
событий , Application_Start
, Session_Start
, Application_End
и Session_End
.
Примечание
При развертывании приложения ASP.NET необходимо скопировать файл в Global.asax
рабочую среду. Файл Global.asax.vb
, созданный в WAP, не требуется копировать в рабочую среду, так как этот код компилируется в сборку проекта.
Обработчики событий, созданные шаблоном глобального класса приложения Visual Studio, не являются исчерпывающими. Вы можете добавить обработчик событий для любого HttpApplication
события, назвав обработчик Application_EventName
событий . Например, можно добавить следующий код в Global.asax
файл, чтобы создать обработчик событий для AuthorizeRequest
события:
Sub Application_AuthorizeRequest(ByVal sender As Object, ByVal e As EventArgs)
' Event handler code
End Sub
Аналогичным образом можно удалить любые обработчики событий, созданные шаблоном глобального класса приложения, которые не нужны. В этом руководстве требуется только обработчик событий для Error
события. Вы можете удалить другие обработчики событий из Global.asax
файла.
Примечание
Http-модули предлагают другой способ определения обработчиков событий для HttpApplication
событий. Модули HTTP создаются как файл класса, который можно поместить непосредственно в проект веб-приложения или разделить в отдельную библиотеку классов. Так как они могут быть разделены в библиотеку классов, http-модули предлагают более гибкую и многоразовую модель для создания HttpApplication
обработчиков событий. Global.asax
Хотя файл зависит от веб-приложения, в котором он находится, http-модули можно скомпилировать в сборки, после чего добавить модуль HTTP на веб-сайт так же просто, как удалить сборку в Bin
папку и зарегистрировать модуль в Web.config
. В этом руководстве не рассматривается создание и использование модулей HTTP, но две библиотеки ведения журнала ошибок, используемые в следующих двух руководствах, реализуются как модули HTTP. Дополнительные сведения о преимуществах модулей HTTP см. в статье Использование модулей HTTP и обработчиков для создания подключаемых компонентов ASP.NET.
Получение сведений о необработанных исключениях
На этом этапе у нас есть файл Global.asax с обработчиком Application_Error
событий. При выполнении этого обработчика событий необходимо уведомить разработчика об ошибке и записать в журнал ее сведения. Для выполнения этих задач сначала необходимо определить сведения о возником исключении. Используйте метод объекта GetLastError
Server для получения сведений о необработанных исключениях, вызвавших Error
событие.
Sub Application_Error(ByVal sender As Object, ByVal e As EventArgs)
' Get the error details
Dim lastErrorWrapper As HttpException = _
CType(Server.GetLastError(), HttpException)
End Sub
Метод GetLastError
возвращает объект типа Exception
, который является базовым типом для всех исключений в платформа .NET Framework. Однако в приведенном выше коде объект Exception, возвращенный GetLastError
, приводится к объекту HttpException
. Error
Если событие вызывается из-за исключения во время обработки ресурса ASP.NET, то созданное исключение помещается в HttpException
. Чтобы получить фактическое исключение, которое ускорит событие Error, используйте InnerException
свойство . Error
Если событие возникло из-за исключения на основе HTTP, например запроса несуществующей страницы, HttpException
создается исключение , но внутреннее исключение отсутствует.
В следующем коде GetLastErrormessage
используется для получения сведений об исключении, которое активировало Error
событие, сохраняя HttpException
в переменной с именем lastErrorWrapper
. Затем он сохраняет тип, сообщение и трассировку стека исходного исключения в трех строковых переменных, проверяя, является ли lastErrorWrapper
фактическим исключением, вызвавшее Error
событие (в случае исключений на основе HTTP), или является ли это просто оболочкой для исключения, которое было создано при обработке запроса.
Sub Application_Error(ByVal sender As Object, ByVal e As EventArgs)
' Get the error details
Dim lastErrorWrapper As HttpException = _
CType(Server.GetLastError(), HttpException)
Dim lastError As Exception = lastErrorWrapper
If lastErrorWrapper.InnerException IsNot Nothing Then
lastError = lastErrorWrapper.InnerException
End If
Dim lastErrorTypeName As String = lastError.GetType().ToString()
Dim lastErrorMessage As String = lastError.Message
Dim lastErrorStackTrace As String = lastError.StackTrace
End Sub
На этом этапе у вас есть все сведения, необходимые для написания кода, который будет записывать сведения об исключении в таблицу базы данных. Вы можете создать таблицу базы данных со столбцами для каждой из интересующих ошибок ( тип, сообщение, трассировка стека и т. д.), а также другие полезные сведения, такие как URL-адрес запрошенной страницы и имя пользователя, вошедшего в систему. Затем в обработчике Application_Error
событий необходимо подключиться к базе данных и вставить запись в таблицу. Аналогичным образом можно добавить код для оповещения разработчика об ошибке по электронной почте.
Библиотеки ведения журнала ошибок, рассмотренные в следующих двух руководствах, предоставляют такие функциональные возможности, поэтому нет необходимости создавать эти ведения журнала ошибок и уведомления самостоятельно. Однако, чтобы продемонстрировать, что Error
возникает событие и что Application_Error
обработчик событий можно использовать для регистрации сведений об ошибке и уведомления разработчика, давайте добавим код, который уведомляет разработчика о возникновении ошибки.
Уведомление разработчика при возникновении необработанного исключения
При возникновении необработанного исключения в рабочей среде важно предупредить группу разработчиков, чтобы они могли оценить ошибку и определить, какие действия необходимо предпринять. Например, если при подключении к базе данных возникает ошибка, вам потребуется удвоить проверка строка подключения и, возможно, отправить запрос в службу поддержки в вашей компании по размещению веб-сайтов. Если исключение возникло из-за ошибки программирования, может потребоваться добавить дополнительный код или логику проверки, чтобы предотвратить такие ошибки в будущем.
Классы платформа .NET Framework в System.Net.Mail
пространстве имен упрощают отправку сообщения электронной почты. КлассMailMessage
представляет сообщение электронной почты и имеет такие свойства, как To
, From
, Subject
, Body
и Attachments
. SmtpClass
Используется для отправки MailMessage
объекта с помощью указанного SMTP-сервера; параметры SMTP-сервера можно указать программным или декларативным способом в элементе<system.net>
Web.config file
в . Дополнительные сведения об отправке сообщений электронной почты в приложении ASP.NET проверка в статьях Отправка Email с сайта веб-страницы ASP.NET и Вопросы и ответы по System.Net.Mail.
Примечание
Элемент <system.net>
содержит параметры SMTP-сервера, используемые классом при отправке SmtpClient
сообщения электронной почты. Вероятно, у вашей компании по размещению веб-сайтов есть SMTP-сервер, который можно использовать для отправки электронной почты из приложения. Дополнительные сведения о параметрах SMTP-сервера, которые следует использовать в веб-приложении, см. в разделе поддержки вашего веб-узла.
Добавьте следующий код в Application_Error
обработчик событий, чтобы отправить разработчику сообщение электронной почты при возникновении ошибки:
Sub Application_Error(ByVal sender As Object, ByVal e As EventArgs)
' Get the error details
Dim lastErrorWrapper As HttpException = _
CType(Server.GetLastError(), HttpException)
Dim lastError As Exception = lastErrorWrapper
If lastErrorWrapper.InnerException IsNot Nothing Then
lastError = lastErrorWrapper.InnerException
End If
Dim lastErrorTypeName As String = lastError.GetType().ToString()
Dim lastErrorMessage As String = lastError.Message
Dim lastErrorStackTrace As String = lastError.StackTrace
Const ToAddress As String = "support@example.com"
Const FromAddress As String = "support@example.com"
Const Subject As String = "An Error Has Occurred!"
' Create the MailMessage object
Dim mm As New MailMessage(FromAddress, ToAddress)
mm.Subject = Subject
mm.IsBodyHtml = True
mm.Priority = MailPriority.High
mm.Body = string.Format( _
"<html>" & vbCrLf & _
" <body>" & vbCrLf & _
" <h1>An Error Has Occurred!</h1>" & vbCrLf & _
" <table cellpadding=""5"" cellspacing=""0"" border=""1"">" & vbCrLf & _
" <tr>" & vbCrLf & _
" <tdtext-align: right;font-weight: bold"">URL:</td>" & vbCrLf & _
" <td>{0}</td>" & vbCrLf & _
" </tr>" & vbCrLf & _
" <tr>" & vbCrLf & _
" <tdtext-align: right;font-weight: bold"">User:</td>" & vbCrLf & _
" <td>{1}</td>" & vbCrLf & _
" </tr>" & vbCrLf & _
" <tr>" & vbCrLf & _
" <tdtext-align: right;font-weight: bold"">Exception Type:</td>" & vbCrLf & _
" <td>{2}</td>" & vbCrLf & _
" </tr>" & vbCrLf & _
" <tr>" & vbCrLf & _
" <tdtext-align: right;font-weight: bold"">Message:</td>" & vbCrLf & _
" <td>{3}</td>" & vbCrLf & _
" </tr>" & vbCrLf & _
" <tr>" & vbCrLf & _
" <tdtext-align: right;font-weight: bold"">Stack Trace:</td>" & vbCrLf & _
" <td>{4}</td>" & vbCrLf & _
" </tr> " & vbCrLf & _
" </table>" & vbCrLf & _
" </body>" & vbCrLf & _
"</html>", _
Request.RawUrl, _
User.Identity.Name, _
lastErrorTypeName, _
lastErrorMessage, _
lastErrorStackTrace.Replace(Environment.NewLine, "<br />"))
'Attach the Yellow Screen of Death for this error
Dim YSODmarkup As String = lastErrorWrapper.GetHtmlErrorMessage()
If Not String.IsNullOrEmpty(YSODmarkup) Then
Dim YSOD As Attachment = _
Attachment.CreateAttachmentFromString(YSODmarkup, "YSOD.htm")
mm.Attachments.Add(YSOD)
End If
' Send the email
Dim smtp As New SmtpClient()
smtp.Send(mm)
End Sub
Хотя приведенный выше код довольно длинный, основная его часть создает HTML-код, который отображается в сообщении электронной почты, отправленном разработчику. Код начинается с ссылки на , HttpException
возвращенный методом GetLastError
(lastErrorWrapper
). Фактическое исключение, вызванное запросом, извлекается с помощью lastErrorWrapper.InnerException
и назначается переменной lastError
. Сведения о трассировке типа, сообщения и стека извлекаются из lastError
трех строковых переменных и хранятся в ней.
Затем создается объект с MailMessage
именем mm
. Текст сообщения электронной почты имеет формат HTML и отображает URL-адрес запрошенной страницы, имя текущего пользователя, выполнившего вход в систему, и сведения об исключении (тип, сообщение и трассировка стека). Одна из интересных вещей в классе заключается в HttpException
том, что вы можете создать HTML-код, используемый для создания сведений об исключении Желтый экран смерти (YSOD), вызвав метод GetHtmlErrorMessage. Этот метод используется здесь для получения разметки YSOD сведений об исключении и добавления ее в сообщение электронной почты в качестве вложения. Один из предостережений: если исключение, которое вызвало Error
событие, было исключением на основе HTTP (например, запрос несуществующей страницы), метод GetHtmlErrorMessage
вернет null
.
Последним шагом является отправка MailMessage
. Для этого создается новый SmtpClient
метод и вызывается его Send
метод.
Примечание
Перед использованием этого кода в веб-приложении необходимо изменить значения в ToAddress
константах и FromAddress
с support@example.com на любой адрес электронной почты, на который должно отправляться уведомление об ошибке. Вам также потребуется указать параметры SMTP-сервера в <system.net>
разделе в Web.config
. Обратитесь к поставщику веб-узла, чтобы определить параметры SMTP-сервера для использования.
При наличии этого кода при возникновении ошибки разработчику отправляется сообщение электронной почты, в котором приводится сводка ошибки и включается YSOD. В предыдущем руководстве мы продемонстрировали ошибку среды выполнения, посетив Genre.aspx и передав недопустимое ID
значение через строку запроса, например Genre.aspx?ID=foo
. При посещении страницы с Global.asax
файлом создается тот же пользовательский интерфейс, что и в предыдущем руководстве. В среде разработки вы по-прежнему будете видеть желтый экран исключения, а в рабочей среде — настраиваемую страницу ошибок. В дополнение к существующему поведению разработчику отправляется сообщение электронной почты.
На рисунке 2 показано сообщение электронной почты, полученное при посещении Genre.aspx?ID=foo
. Текст сообщения электронной почты обобщает сведения об исключении, а вложение YSOD.htm
отображает содержимое, которое отображается в YSOD сведений об исключении (см . рис. 3).
Рис. 2. Разработчику отправляется уведомление Email при возникновении необработанного исключения
(Щелкните для просмотра полноразмерного изображения)
Рис. 3. Уведомление Email включает сведения об исключении YSOD в виде вложения
(Щелкните для просмотра полноразмерного изображения)
Как насчет использования пользовательской страницы ошибок?
В этом руководстве показано, как использовать Global.asax
и Application_Error
обработчик событий для выполнения кода при возникновении необработанного исключения. В частности, мы использовали этот обработчик событий для уведомления разработчика об ошибке; Мы можем расширить его, чтобы также регистрировать сведения об ошибках в базе данных. Наличие обработчика Application_Error
событий не влияет на взаимодействие с конечным пользователем. Они по-прежнему видят настроенную страницу ошибки, будь то сведения об ошибке YSOD, ошибка времени выполнения YSOD или пользовательская страница ошибки.
Естественно задаться вопросом, Global.asax
необходимы ли файл и Application_Error
событие при использовании пользовательской страницы ошибок. При возникновении ошибки пользователю отображается пользовательская страница ошибок, так почему мы не можем поместить код для уведомления разработчика и записать сведения об ошибке в класс кода программной части настраиваемой страницы ошибок? Хотя вы, безусловно, можете добавить код в класс кода программной части пользовательской страницы ошибок, у вас нет доступа к сведениям об исключении, которое вызвало Error
событие при использовании метода, который мы изучили в предыдущем руководстве. GetLastError
Вызов метода со страницы пользовательской ошибки возвращает .Nothing
Причина такого поведения заключается в том, что пользовательская страница ошибки достигается через перенаправление. Когда необработанное исключение достигает среды выполнения ASP.NET, подсистема ASP.NET вызывает событие Error
(которое выполняет Application_Error
обработчик событий), а затем перенаправляет пользователя на пользовательскую страницу ошибок, выдавая Response.Redirect(customErrorPageUrl)
. Метод Response.Redirect
отправляет клиенту ответ с кодом состояния HTTP 302, предписывая браузеру запросить новый URL-адрес, а именно настраиваемую страницу ошибки. Затем браузер автоматически запрашивает эту новую страницу. Можно сказать, что пользовательская страница ошибки была запрошена отдельно от страницы, на которой возникла ошибка, так как адресная строка браузера меняется на URL-адрес настраиваемой страницы ошибок (см . рис. 4).
Рис. 4. При возникновении ошибки браузер перенаправляется на URL-адрес настраиваемой страницы ошибок
(Щелкните для просмотра полноразмерного изображения)
Результатом является то, что запрос, в котором произошло необработанное исключение, завершается, когда сервер отвечает перенаправлением HTTP 302. Последующий запрос на пользовательскую страницу ошибок является совершенно новым запросом; к этому моменту обработчик ASP.NET отбрасывает сведения об ошибке и, более того, не может связать необработанное исключение в предыдущем запросе с новым запросом для настраиваемой страницы ошибок. Именно поэтому GetLastError
возвращает при null
вызове из пользовательской страницы ошибок.
Однако пользовательская страница ошибки может быть выполнена во время того же запроса, который вызвал ошибку. Метод Server.Transfer(url)
передает выполнение на указанный URL-адрес и обрабатывает его в рамках того же запроса. Вы можете переместить код в обработчике Application_Error
событий в класс кода программной части пользовательской страницы ошибок, заменив его следующим Global.asax
кодом:
Sub Application_Error(ByVal sender As Object, ByVal e As EventArgs)
' Get the error details
Dim lastErrorWrapper As HttpException = _
CType(Server.GetLastError(), HttpException)
If lastErrorWrapper.GetHttpCode() = 404 Then
Server.Transfer("~/ErrorPages/404.aspx")
Else
Server.Transfer("~/ErrorPages/Oops.aspx")
End If
End Sub
Теперь при возникновении Application_Error
необработанного исключения обработчик событий передает управление на соответствующую пользовательскую страницу ошибок на основе кода состояния HTTP. Так как управление было передано, пользовательская страница ошибок имеет доступ к необработанным сведениям об исключении через Server.GetLastError
и может уведомить разработчика об ошибке и записать в журнал ее сведения. Вызов Server.Transfer
останавливает подсистему ASP.NET перенаправление пользователя на пользовательскую страницу ошибок. Вместо этого содержимое настраиваемой страницы ошибок возвращается в качестве ответа на страницу, которая вызвала ошибку.
Сводка
При возникновении необработанного исключения в веб-приложении ASP.NET среда выполнения ASP.NET вызывает Error
событие и отображает настроенную страницу ошибки. Мы можем уведомить разработчика об ошибке, записать в журнал ее сведения или обработать ее каким-либо другим способом, создав обработчик событий для события Error. Существует два способа создания обработчика событий для HttpApplication
таких событий, как Error
: в Global.asax
файле или из http-модуля. В этом руководстве показано, как создать Error
обработчик событий в Global.asax
файле, который уведомляет разработчиков об ошибке с помощью сообщения электронной почты.
Создание обработчика Error
событий полезно, если необходимо обрабатывать необработанных исключений каким-либо уникальным или настраиваемым способом. Однако создание собственного Error
обработчика событий для регистрации исключения или уведомления разработчика не является наиболее эффективным использованием вашего времени, так как уже существуют бесплатные и простые в использовании библиотеки ведения журнала ошибок, которые можно настроить за считанные минуты. В следующих двух учебниках рассматриваются две такие библиотеки.
Счастливое программирование!
Дополнительные материалы
Дополнительные сведения по темам, рассматриваемым в этом руководстве, см. в следующих ресурсах:
- ASP.NET общие сведения о модулях HTTP и обработчиках HTTP
- Корректное реагирование на необработанное исключение — обработка необработанных исключений
HttpApplication
Класс и объект приложения ASP.NET- Обработчики HTTP и модули HTTP в ASP.NET
- Отправка Email в ASP.NET
- Общие сведения о
Global.asax
файле - Использование модулей и обработчиков HTTP для создания подключаемых компонентов ASP.NET
- Работа с файлом ASP.NET
Global.asax
- Работа с
HttpApplication
экземплярами
Обратная связь
https://aka.ms/ContentUserFeedback.
Ожидается в ближайшее время: в течение 2024 года мы постепенно откажемся от GitHub Issues как механизма обратной связи для контента и заменим его новой системой обратной связи. Дополнительные сведения см. в разделеОтправить и просмотреть отзыв по