Exception Handling


The safest bet is to assume you can’t detect and handle every unexpected circumstance and that exceptions will inevitably occur. When an exception occurs, you should follow a standard series of steps—basic do’s and don’ts—to handle the exception. Here is what your system should and shouldn’t do when designing your application to cope with exceptions:

  • DO write Try…Catch or On Error GoTo exception handling on all database interactions. Pay special attention to where the database is being accessed for the first time—because if there is a network outage or a bad file path to the database, this is where it will be first detected.

  • DO report an error to the user explaining briefly what went wrong and what she should do next. Examples of good messages are:

    • “Unable to log in. Please try again.”

    • “Cannot create management report. Contact helpdesk for assistance.”

    • “Could not open database. E-mail support@microsoft.com for help.”

  • DO give the user information about who to contact when something goes wrong. Ideally, this should be in the text of the error that the system reports to the user.

  • DO log full details of the exception somewhere so that the administrator, helpdesk, or developer can find out what happened.

  • DON’T give too much information in the error message to the user. For example, each of the following error messages is flawed:

    • “Username is valid, but password is incorrect. Please try again.”

    • “Could not open file \\NetworkServer\Databases\MyDatabase.mdb.”

    • “Invalid SQL statement SELECT * FROM Employee WHERE username = ‘RKing*’”

The reason these are flawed error messages is that they divulge too much information about the inner workings of the system. The first example informs the intruder he has entered a valid username and invites him to try other passwords until he gets it right. The second example tells the intruder the precise location of the database the system is using—if he can gain access to the network, the intruder now knows where to look to find your application’s database. The third flawed message reveals the contents of the SQL statement, which in some cases will allow the intruder to adjust his input to twist the SQL statement to some nefarious purpose. You should never expose the inner workings of the system to the end user. For an intruder intent on breaking in, doing so might give away vital information about the system. A good practice is to never directly echo back to the user the information that Visual Basic .NET gives the application about the error. Usually this information is irrelevant to anyone but the application’s developer. Instead, your application should give a message in terminology the user will understand.

Add exception handling to the employee management system

In this exercise, you will add a procedure to SecurityLibrary.vb that logs details about an exception to the event log. You will then add exception handling to the employee management system clsEmployee class to catch exceptions when retrieving information from the database.

  1. In Microsoft Visual Basic .NET, open the solution CH08_ErrorHandling\EMS\Start\EMS.sln.

  2. Before adding the exception-handling code, let’s create an exception case. Open MainModule.vb, and change the line of code that sets the database name from

    Const DatabaseName As String = "EmployeeDatabase.mdb"

    to

    Const DatabaseName As String = "Invalid.mdb"
  3. Now press F5 to run the employee management system. When you try to log in, you will see an exception dialog box that should look something like this:

    click to expand

Interestingly, the exception dialog box changes when the application is run outside of the Visual Basic .NET debugger. What your users would see in that case is shown here:

click to expand

This unhandled exception gives too much information about what went wrong.

  1. Open SecurityLibrary.vb, and add the following code to the end of the module. This code logs an exception to the Windows event log. If the version of Windows is Windows 98 or Windows ME, the exception is added to a file in the Application Data directory.

    Namespace EventLog
    Module EventLog
    Sub LogException(ByVal ex As Exception)
    ’If this is an NT based operating system
    ‘(Windows NT4, Windows2000,
    ’Windows XP, Windows Server 2003)
    ‘then add the exception to the
    ’application event log.
    ’If the operating system is Windows98 or WindowsME, then
    ’append it to a <appname>.log file in the
    ‘ApplicationData directory
    Dim strApplicationName As String
    Dim blnIsWin9X As Boolean
    Dim FileNumber As Integer = -1
    Try
    ’Get name of assembly
    strApplicationName = _
    System.Reflection.Assembly.GetExecutingAssembly.GetName.Name
    blnIsWin9X = (System.Environment.OSVersion.Platform <> _
    PlatformID.Win32NT)
    If blnIsWin9X Then
    ’Windows98 or WindowsME
    Dim strTargetDirectory, strTargetPath As String
    ’Get Application Data directory, and create path
    strTargetDirectory = System.Environment.GetFolderPath( _
    Environment.SpecialFolder.ApplicationData)
    strTargetPath = strTargetDirectory & "\" & _
    strApplicationName & ".Log"
    ’Append to the end of the log (or create a new one
    ’if it doesn’t already exist)
    FileNumber = FreeFile()
    FileOpen(FileNumber, strTargetPath, OpenMode.Append)
    PrintLine(FileNumber, Now)
    PrintLine(FileNumber, ex.ToString)
    FileClose(FileNumber)
    Else
    ’WinNT4, Win2K, WinXP, Windows.NET
    System.Diagnostics.EventLog.WriteEntry(_
    strApplicationName, _
    ex.ToString, _
    EventLogEntryType.Error)
    End If
    Finally
    If FileNumber > -1 Then FileClose(FileNumber)
    End Try
    End Sub
    End Module
    End Namespace

  2. Open the class clsEmployee.cls, and locate the Create function. This function takes a username, retrieves the profile data from the database, and stores it in the class. Add a Try…Catch exception handler to make the code look like the following:

    Public Shared Function Create(ByVal strUserName As String) _
    As clsEmployee
    Dim employee As clsEmployee
    Try
    employee = New clsEmployee()
    'Avoid a SQL injection attack: Insure username contains no
    'dangerous symbols such as apostrophes or dashes (SQL comment)
    If Not ValidateInput.IsValidUserName(strUserName) Then
    employee.m_IsValidUser = False
    Return employee
    End If

    'Avoid a SQL injection attack: Use a parameterized query to load
    'information from the employee table
    Dim strSQL As String = _
    "Select * from Employee where Username = " & _
    "@ParameterUserName"

    Dim cn As OleDbConnection
    Dim cmd As OleDbCommand
    Dim dr As OleDbDataReader

    cn = New OleDbConnection(G_CONNECTIONSTRING)
    cmd = New OleDbCommand(strSQL, cn)
    cmd.CommandType = CommandType.Text
    cmd.Parameters.Add("@ParameterUserName", strUserName)

    cn.Open()
    dr = cmd.ExecuteReader()

    If dr.Read() Then
    employee = New clsEmployee()
    employee.FirstName = CStr(dr("FirstName"))
    employee.LastName = CStr(dr("LastName"))
    employee.FullName = CStr(dr("Fullname"))
    employee.m_PasswordHash = CStr(dr("PasswordHash"))
    employee.m_BankAccountEncrypted = _
    CStr(dr("BankAccountEncrypted"))
    employee.m_Username = strUserName
    employee.m_IsValidUser = True
    End If

    'Obtain the list of roles associated with the user and assigns
    'the principal--containing the user and roles--to the
    ‘current thread.
    SetPrincipalPolicy(employee.m_Username)

    Catch ex As Exception
    'If an exception occurs, the ex variable is created
    'and will hold an object with all the exception information
    EventLog.LogException(ex)
    employee.m_IsValidUser = False
    End Try

    Return employee
    End Function

  3. Now press F5 to run the application, and attempt to log in. Instead of receiving an ugly exception, your users are told, “Could not log in. Please try again.” The exception information is saved to the application event log. You can view the application event log by choosing Run from the Start menu, typing EventVwr.exe, and pressing Enter. In the application event log, you will see an entry for the exception you just logged, as shown here:

    click to expand

  4. Before continuing, change the database path back to its correct setting. Open MainModule.vb, and change the line of code that sets the database name from

    Const DatabaseName As String = "Invalid.mdb"

    to

    Const DatabaseName As String = "EmployeeDatabase.mdb"

start sidebar
Try…Catch or On Error GoTo

Visual Basic .Net supports two forms of exception handling: Try…Catch exception handling (as used in the previous example) and the older style On Error GoTo exception handling. You might be wondering, “Which should I use?” There is no definitive answer. Which method you choose is mainly a matter of personal preference, although Try…Catch exception handling has an edge over On Error GoTo for several reasons. Try…Catch exception handling offers a finer degree of tuning because you can nest Try…Catch exception blocks within other Try…Catch exception blocks. Also, you can add several Catch clauses to handle different types of exceptions and a Finally clause to run code at the end of processing whether an exception occurred or not. The following code snippet shows the syntax for targeted exception handling and code that runs in a Finally clause:

Try
’Some code
Catch exFileNotFound As System.IO.FileNotFoundException ’Exception handler for file not found
Catch ex As Exception
’Exception handler for all other types of exceptions
Finally
’Code that always runs at the end of processing
End Try

Try…Catch exception handling also results in slightly cleaner compiled code, although the effects of this are negligible. You can mix and match the two types of exception handling, using On Error GoTo in one function and Try…Catch in another. However, the Visual Basic compiler will not let you use both On Error GoTo and Try…Catch in the same function.

end sidebar




Security for Microsoft Visual Basic  .NET
Security for Microsoft Visual Basic .NET
ISBN: 735619190
EAN: N/A
Year: 2003
Pages: 168

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net