# Friday, May 29, 2009

Getting errors nicely via email from your website the vb.net version

For the c# version look here -> http://www.myfriedmind.com/techBlog/2009/05/29/GettingErrorsNicelyViaEmailFromYourWebsiteTheCVersion.aspx

It is always nice to get notified that there is an error on your website in some other way than a user on the other end of the phone.

One of the nicest ways I know of in .net is to use the Application_Error portion of Global.asax to shoot me an email listing the information that is needed. I have included some basic code below but you can feel free to modify it as you choose. For example you may prefer to include the System.Net.Mail info on the SmtpServer in the web.config so you can use it on other portions of the site rather than repeat it.

In the code I use reflection to roll through both the Request object and the Exception that is passed. You can modify it if you want to display more (such as innerexceptions, etc) or to exclude, but Reflection can be nice in pulling up all the data quickly.

=================
In vb.net

In Web.Config
        <customErrors mode="On" defaultRedirect="~/ErrorOnWebsite.aspx"/>

In Global.asax (don't do this and you get an endless loop!)
    Sub Application_Error(ByVal sender As Object, ByVal e As EventArgs)
        Server.Transfer("~/ErrorOnWebsite.aspx")
    End Sub

On ErrorOnWebsite.aspx (you don't actually have to use a label, you can provide some other means of apology)
        <asp:Label runat="server" ID="lblApology"></asp:Label>

This is Error.OnWebsite.aspx.vb (I like code-behinds) - note the use of the HtmlTextWriter and Reflection!

Imports System
Imports System.IO
Imports System.Net.Mail
Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports System.Reflection

Partial Class ErrorOnPage
    Inherits System.Web.UI.Page

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Dim exc As Exception = Server.GetLastError()

        If (exc Is Nothing) Then
            ' there is no error, why are they here?
            Response.Redirect("~/")
        Else
            SendNotificationEmail(exc)
            WriteApology()
            Server.ClearError()
        End If
    End Sub

    Private Sub WriteApology()
        lblApology.Text = "Oops, sorry, the master of light and sound has been notified..."
    End Sub

    Private Sub SendNotificationEmail(ByVal exc As Exception)
        ' Create the format holder for the data, I like tables...
        Dim _infoTable As Table = New Table()
        _infoTable.Attributes.Add("border", "1")
        _infoTable.Attributes.Add("cellpadding", "3")

        Dim _infoRow As TableRow
        Dim _infoNameCell As TableCell
        Dim _infoDataCell As TableCell

        _infoRow = New TableRow()
        _infoNameCell = New TableCell()
        _infoNameCell.Text = "Server Request Properties"
        _infoNameCell.BackColor = System.Drawing.Color.Gray
        _infoNameCell.ColumnSpan = 2
        _infoRow.Cells.Add(_infoNameCell)
        _infoTable.Rows.Add(_infoRow)

        ' I like to use reflection because I hate to type...
        Dim _requestType As Type = Request.GetType()
        Dim _pInfo As PropertyInfo

        For Each _pInfo In _requestType.GetProperties()

            If (Not _pInfo.Name = "Item") Then

                _infoRow = New TableRow()

                _infoNameCell = New TableCell()
                _infoNameCell.Text = _pInfo.Name
                _infoRow.Cells.Add(_infoNameCell)

                _infoDataCell = New TableCell()
                Dim _value As Object = _pInfo.GetValue(Request, Nothing)
                If _value Is Nothing Then
                    _infoDataCell.Text = ""
                Else
                    _infoDataCell.Text = Server.HtmlEncode(_value.ToString())
                End If
                _infoRow.Cells.Add(_infoDataCell)

                _infoTable.Rows.Add(_infoRow)
            End If
        Next

        _infoRow = New TableRow()
        _infoNameCell = New TableCell()
        _infoNameCell.Text = "Exception Properties"
        _infoNameCell.BackColor = System.Drawing.Color.Gray
        _infoNameCell.ColumnSpan = 2
        _infoRow.Cells.Add(_infoNameCell)
        _infoTable.Rows.Add(_infoRow)

        Dim _exceptionType As Type = exc.GetType()
        For Each _pInfo In _exceptionType.GetProperties()        
            _infoRow = New TableRow()

            _infoNameCell = New TableCell()
            _infoNameCell.Text = _pInfo.Name
            _infoRow.Cells.Add(_infoNameCell)

            _infoDataCell = New TableCell()
            Dim _value As Object = _pInfo.GetValue(exc, Nothing)
            If (_value Is Nothing) Then
                _infoDataCell.Text = ""
            Else
                _infoDataCell.Text = Server.HtmlEncode(_value.ToString())
            End If
            _infoRow.Cells.Add(_infoDataCell)

            _infoTable.Rows.Add(_infoRow)
        Next

        ' note the use of the HtmlTextWriter to render the table
        ' into a string
        Dim _bodyWriter As StringWriter = New StringWriter()
        Dim _writeToBody As HtmlTextWriter = New HtmlTextWriter(_bodyWriter)
        _infoTable.RenderControl(_writeToBody)

        Dim _message As MailMessage = New MailMessage("error@mysite.com", "myemail@mysite.com")
        _message.Subject = String.Format("Error on website - {0}", exc.Message)
        _message.Body = _bodyWriter.ToString()
        _message.IsBodyHtml = True

        Dim _mailClient As SmtpClient = New SmtpClient("mymailserver")
        _mailClient.Send(_message)

    End Sub

End Class

Monday, June 15, 2009 9:24:05 PM (Central Daylight Time, UTC-05:00)
WOW.. this is awesome. Going to try adding it tomorrow.
Susan
Comments are closed.