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 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 \NetworkServerDatabasesMyDatabase.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_ErrorHandlingEMSStartEMS.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:

    Exception Handling

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:

Exception Handling

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:

    Exception Handling
  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"
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.221.224.144