If the file name is entered manually, the chance that someone will enter it wrong is high. If you don't do anything, this is what the user will see:
Click Here to display the illustration
Your users will have a much better experience if you give them a chance to enter the file name correctly like this:
Click Here to display the illustration
Here's a code example showing how this exception might be used in a file handling situation. This code displays a form that allows your user to enter the name of a file:
Dim FileName As String Do NewFileDialog.ShowDialog() FileName = NewFileDialog.theFileName Loop While OpenTheFile(FileName) <> 0
OpenTheFile is a Function that only returns "0" when the file is found:
Private Function OpentheFile(ByVal FN) As Integer Try Dim theFile As FileStream theFile = File.OpenRead(FN) Return 0 Catch ex As FileNotFoundException MsgBox("The system could not find the file." & vbNewLine & "Is the name correct?") Return -1 End Try End Function
The "down" side to detailed exception handling is that the Try-Catch block will only catch the exceptions that are handled. In this case, for example, suppose the user enters the wrong drive identifier. The code above will then crash with a DirectoryNotFoundException instead. That exception processing isn't very complete.
You can solve this new problem by adding another Catch block. Be sure to add catch blocks in order from most specific to least specific. After an error is caught by any of the blocks, none of the other blocks will be called.
Try Dim theFile As FileStream theFile = File.OpenRead(FN) Return 0 Catch ex As FileNotFoundException MsgBox("The system could not find the file." & vbNewLine & "Is the name correct?") Return -1 Catch ex As DirectoryNotFoundException MsgBox("The directory you entered isn't correct.") Return -2 End Try
Or, you could use a more inclusive exception. This one will catch both exceptions.
Catch ex As IOException MsgBox("The system could not open the file." & vbNewLine & "Please Try again.") Return -3 End Try
In fact, if you simply don't enter an exception type at all, all exceptions will be caught:
Try Dim theFile As FileStream theFile = File.OpenRead(FN) Return 0 Catch MsgBox("The system could not open the file." & vbNewLine & "Or, maybe it was some other error.") Return -4 End Try
Since exceptions are objects, they have their own methods and properties. For example, if you used IOException, you could then use the GetBaseException method of the Ex object (a local instance of the Exception object defined in this code) to narrow down to exactly what caused the problem.
In addition to the many exceptions provided by .NET, you can also Throw your own exceptions. You should define an exception by creating a class that inherits from System.Exception so your code can test for your exception. (The code will work if you just throw a new exception, but then the code that catches it won't be able to determine if it's your exception or some other error.)
The minimum you need is:
Public Class myException Inherits System.Exception End Class
You might want to make your exception class more complete by calling the System.Exception (the base class) New procedure and providing for a possible text argument:
Public Class MyException Inherits System.Exception Public Sub New() MyBase.New() End Sub Public Sub New(ByVal Message As String) MyBase.New(message) End Sub End Class
One way to use a custom exception is to enforce some universal processing. For example, suppose you're coding a financial routine and any code calling it must provide special processing if an amount exceeds 99,999. This code will do it:
Public Class GetAmountDialog Public Ex As New AmountTooBigException Private Sub ProcessAmount_Click( ByVal sender As System.Object, ByVal e As System.EventArgs ) Handles ProcessAmount.Click If CDec(AmountIn.Text) > 99999 Then Throw Ex Me.Hide() End Sub End Class Public Class AmountTooBigException Inherits System.Exception End Class
If a routine that uses this class processes an amount bigger than 99999 and fails to provide a Try-Catch block, then the application will crash on an AmountTooBigException error.
Even more sophisticated exception handling can be programmed by nesting a hierarchy of exception handling blocks. These blocks can be in the same procedure or in a previous procedure that called the one that produced an error. In the example above, a previous procedure handles the exception that is thrown by GetAmountDialog. In this way, the most specific exceptions are handled by the inner Try-Catch blocks. If an inner block can't handle an exception, then .NET will pass it to an outer block (the exception is passed up the call stack) that normally handles more general exceptions. If the exception is never handled, however, the application will still crash.