Обработка исключений
Последнее обновление: 30.10.2015
В процессе выполнения программы нередко возникают такие ситуации, которые трудно или даже невозможно предусмотреть во время создания программы.
Например, при передаче файла по сети может неожиданно оборваться сетевое подключение. Такие ситуации называются исключениями.
Чтобы программа неожиданно не зависла в таких ситуациях, программисту нужно вводить в нее обработку исключений.
Для обработки исключений в языке VB.NET имеется конструкция Try…Catch..Finally. Ее использование выглядит следующим образом:
Sub Main() Dim a(3) As Integer Try a(5) = 3 Catch ex As Exception Console.WriteLine(ex.Message) Finally Console.WriteLine("Finally block") End Try Console.ReadLine() End Sub
В данном случае у нас как раз и возникает исключение, так как в массиве a только 4 элемента, а мы пытаемся присвоить значение шестому элементу.
При использовании блока Try…Catch..Finally сначала выполняются все инструкции между операторами Try и
Catch.
И если вдруг в каком-то месте кода возникает исключение, то обычный порядок выполнения кода останавливается и программа переходит к выражению Catch.
Это выражение имеет следующий синтаксис: Catch имя_переменной As тип_исключения
. В данном случае у нас объявляется переменная ex, которая
имеет тип Exception. При чем если возникшее исключение не является исключением типа, указанного в выражении Catch, то оно не обрабатывается,
а программа просто зависает или выбрасывает сообщение об ошибке. Так как тип Exception
является базовым типом для всех исключений, то в
выражении Catch ex As Exception
абсолютно все исключения.
В нашем случае мы просто выводим сообщение об исключении на экран с помощью свойства Message
, определенное в классе Exception
.
Далее в любом случае выполняется блок после оператора Finally
. Но этот блок необязательный, и его можно при обработке исключений опускать.
В случае, если в ходе программы исключений не возникнет, то программа не будет выполнять блок Catch, сразу перейдет к блоку Finally,
если он имеется.
Разработка собственных исключений
Мы можем создать свои собственные классы исключений, которые будут обрабатывать нежелательные ситуации. Для примера возьмем класс
Algorithm
, который мы сделали в одной из глав предыдущей части:
Public Class Algorithm Public Shared Function Factorial(x As Integer) As Integer If (x = 1) Then Return 1 Else Return x * Factorial(x - 1) End If End Function Public Shared Function Fibbonachi(x As Integer) As Integer If x = 0 Then Return 1 ElseIf x = 1 Then Return 1 Else Return Fibbonachi(x - 1) + Fibbonachi(x - 2) End If End Function End Class
Факториал и последовательность Фиббоначи определены только для положительных чисел, поэтому если мы передадим в функцию отрицательное число,
возникнет исключительная ситуация. Чтобы ее обработать и создадим класс NegativeNumberException
:
Public Class NegativeNumberException Inherits Exception Sub New() MyBase.New("В качестве параметра передано отрицательное число") End Sub End Class
В этом классе по сути мы только передаем сообщение в конструктор базового класса. Теперь вызовем обработку исключения в методе Factorial
с помощью ключевого слова Throw:
Public Shared Function Factorial(x As Integer) As Integer If x < 0 Then Throw New NegativeNumberException() If (x = 1) Then Return 1 Else Return x * Factorial(x - 1) End If End Function
И теперь, если мы передадим в этот метод отрицательные значения, в блоке Try...Catch
будет обрабатываться исключение NegativeNumberException
:
Try Console.WriteLine(Algorithm.Factorial(-1)) Catch ex As Exception Console.WriteLine(ex.Message) End Try
In visual basic, Try Catch statement is useful to handle unexpected or runtime exceptions which will occur during execution of the program. The Try-Catch statement will contain a Try
block followed by one or more Catch
blocks to handle different exceptions.
In visual basic, whenever an exception occurred in the Try
block, then the CLR (common language runtime) will look for the catch
block that handles an exception. In case, if currently executing method does not contain such a Catch
block, then the CLR will display an unhandled exception message to the user and stops the execution of the program.
Visual Basic Try Catch Syntax
Following is the syntax of handling errors in visual basic using Try, Catch blocks.
Try
‘ Code that may cause exception
Catch ex As Exception
‘ Exception handling
End Try
As per the above syntax, the Try
block will contain the guarded code that may cause an exception so that if any errors occurred in our code, then immediately the code execution will be moved to Catch
block to handle those exceptions.
In Try-Catch statement, the Catch
block will execute only when an exception occurred in the code that is guarded by Try
block.
Visual Basic Try Catch Example
Following is the example of using Try-Catch statement in visual basic to handle the exceptions.
Module Module1
Sub Main(ByVal args As String())
Dim name As String = Nothing
Try
If name.Length > 0 Then ‘ Exception will occur
Console.WriteLine(«Name: « & name)
End If
Catch ex As Exception
Console.WriteLine(«Exception: {0}», ex.Message)
End Try
Console.ReadLine()
End Sub
End Module
If you observe the above code, we used Try
and Catch
blocks to handle runtime or unexpected errors during the execution of the program. Here, we wrote a code that may throw an exception inside of Try
block and in Catch
block we are handling the exception.
When we execute the above code, we will get the result as shown below.
Exception: Object reference not set to an instance of an object.
This is how we can use Try-Catch blocks to handle unexpected or runtime exceptions based on our requirements.
In visual basic, the Try
block must be followed by Catch
or Finally
or both blocks otherwise we will get a compile-time error.
Visual Basic Try with Multiple Catch Blocks
In the above Try-Catch statement example, we used only a single Catch
block with the Exception
base class argument to handle all the exceptions.
In case, if we want to handle a different type of exceptions in different ways, then we can specify multiple Catch
blocks with different exception types in the same Try-Catch statement and this process called an exception filtering.
If we define multiple Catch
blocks with a Try
statement, then the first Catch
statement that can handle an exception will be executed, any following Catch
statements that are even more compatible to handle an exception will be ignored so the order of Catch blocks must be always from most specific to least specific.
Following is the example of defining multiple catch blocks in a Try-Catch statement to handle different exceptions in different ways.
Module Module1
Sub Main(ByVal args As String())
Try
Console.WriteLine(«Enter x value:»)
Dim x As Integer = Integer.Parse(Console.ReadLine())
Console.WriteLine(«Enter y value:»)
Dim y As Integer = Integer.Parse(Console.ReadLine())
Console.WriteLine(x / y)
Catch ex As FormatException
Console.WriteLine(«Input string was not in a correct format.»)
Catch ex As InvalidOperationException
Console.WriteLine(«Not a valid numbers to perform operation»)
Catch ex As DivideByZeroException
Console.WriteLine(«Cannot Divide By Zero»)
End Try
Console.ReadLine()
End Sub
End Module
If you observe the above example, we defined multiple Catch blocks to handle different exception types so that we can easily get know what exact error it is and we can fix it easily.
When we execute the above example, we will get the result as shown below.
Enter x value:
10
Enter y value:
0
Cannot Divide By Zero
This is how we can use multiple Catch blocks with a single Try block to handle different types of exceptions based on our requirements.
Visual Basic Invalid Catch Blocks
In visual basic, defining a parameterless Catch block (Catch) and Catch block with an exception argument (Catch ex As Exception) are not allowed in the same Try-Catch statement because both will do the same thing.
Following is the example of defining an invalid Catch
blocks in same Try-Catch statement.
Try
‘ Code that may cause an exception
Catch
‘ Exception Handling
Catch ex As Exception
‘ Exception Handling
End Try
In case, if we use a parameterless catch block (Catch) or Catch block with an exception argument (Catch ex As Exception) with other Catch blocks, then those parameters must be last otherwise we will get a compile-time error.
Following is the invalid way of defining a multiple catch
blocks with a parameterless Catch
block in same Try-Catch statement.
Try
‘ Code that may cause an exception
Catch
‘ Exception Handling
Catch ex As FormatException
‘ Exception Handling
Catch ex As InvalidOperationException
‘ Exception Handling
End Try
The following are the few points which we need to consider while defining a multiple Catch blocks.
- Multiple Catch blocks with the same exception type are not allowed.
- Defining a parameterless catch block (Catch) and catch block with an exception argument (Catch ex As Exception) are not allowed in the same try-catch statement because both will do the same thing.
- While defining multiple catch blocks, the order of catch blocks must be always from most specific to least specific.
- A parameterless catch block (Catch) or catch block with an exception argument (Catch ex As Exception) must be the last block if we use it with other catch blocks otherwise we will get a compile-time error.
Visual Basic Nested Try-Catch Statements
In visual basic, we can define a Try-Catch statement within another Try-Catch statement based on our requirements. In nested Try-Catch statements, if there isn’t any inner Catch
block with an appropriate exception type, then the exception will flow to the outer Catch
block.
Following is the example of defining nested Try-Catch statements in visual basic.
Module Module1
Sub Main(ByVal args As String())
Try
Try
Console.WriteLine(«Enter x value:»)
Dim x As Integer = Integer.Parse(Console.ReadLine())
Console.WriteLine(«Enter y value:»)
Dim y As Integer = Integer.Parse(Console.ReadLine())
Console.WriteLine(x / y)
Catch ex As FormatException
Console.WriteLine(«Input string was not in a correct format.»)
End Try
Catch ex As Exception
Console.WriteLine(«Exception: « & ex.Message)
End Try
Console.ReadLine()
End Sub
End Module
If you observe the above example, we defined a Try-Catch statement within another Try-Catch statement. Here, if we get any exception other than FormatException in an inner Try-Catch statement, the exception will flow to outer Catch block until it finds an appropriate exception filter.
When we execute the above program, we will get the result like as shown below.
Enter x value:
10
Enter y value:
0
Exception: Attempted to divide by zero.
If you observe the above result, the inner Try-Catch statement has failed to handle the exception so the catch block in the outer Try-Catch statement has been handled the exception.
Visual Basic Try-Catch Overview
The following are the important points which we need to remember about the Try-Catch statement.
- In Try-Catch statement, the
Try
block will hold the code that may raise an exception and in theCatch
block, exception handling can be done. - The Try-Catch statement will contain a
Try
block followed by one or moreCatch
blocks to handle different exceptions. - In visual basic, whenever an exception occurred in the
Try
block, then the CLR (common language runtime) will look for the appropriateCatch
block that handles an exception. - In visual basic, we can use nested Try-Catch statements.
- In nested Try-Catch statements, if there isn’t any inner
Catch
block with an appropriate exception type, then the exception will be caught by an outerCatch
block.
Introduction
Hello and welcome to today’s article. Today I will talk about Exceptions and how to handle them properly in Visual Basic.
Exceptions, What are They?
Simply put: an Exception is an error – something that wrongfully happens in your program. If used properly, exceptions can become close friends. There are mainly three types of exceptions:
-
Compile time exceptions
-
Logic exceptions
-
Run time exceptions
At the end of the day, the area you need to spend the most time on is run time exceptions. Why do I say so? Well, as a developer you need to address any possible error in your application. It may seem obvious, but there are numerous errors that can occur at any given point in your app. With proper planning, you should be able to eradicate most of them; but it is only when you have properly tested your application where you encounter many an unforeseen error. Let me not get ahead of myself here, let me start at the top of the list.
Compile Time Exceptions
Compile time exceptions happen when you compile your application and the compiler informs you about certain errors. These errors may be any of the following:
-
Wrongly spelled objects. These are usually “spelling” errors. For example if you have an object named objValidate and you have referred to it in code as: objVlidate
-
Wrongly referenced Properties and methods. Again, these may be due to a spelling error, or when you have wrongfully referred to an object when you meant a different object. For example: Let me say you have two objects: objA and objB. Now, let me presume further that objA has a Property called Alphabetic and objB has a Property named Numeric. Now, it can get pretty confusing sometimes when you have hundreds of objects in your class(es) and somebody will eventually mix them up by referring to the Alphabetic Property of objB or Numeric Property of objA.
-
Creating objects incorrectly. This is quite common. Many a developer forgets to initialize their objects with the New keyword. It happens to the best of us.
-
Referencing obsolete objects. This happens when you refer to an object that was already disposed.
-
The list goes on, and I could probably go on forever as well, but you get the idea…
Logic Exceptions
Truth be told, this is not an exception where the compiler will tell you what went wrong; in fact, you won’t know until the particular segment of code has been properly tested. How will you know? You will get the wrong results. Let me use a very simple example. Supposed you had a segment of code that is supposed to turn the Form’s BackColor to blue (this is a piece of code where you have to physically see the results for yourself), but your code kept on turning the color to red. This is a logic error. This means that you have to change the logic of your code in order to get the desired result.
Run Time Exceptions
Bad news. Users aren’t perfect and neither is your program. The sooner you accept these two facts, the sooner your apps will be built better. In the planning phase of your app, you must prepare for most of the errors the user may encounter. These include, but are not limited to the following:
-
Attempting to read a file at the wrong location or a file that doesn’t exist
-
Network problems
-
Drive problems
-
Expecting a numeric value when an alphabetic value has been entered
-
Division by 0
-
Having insufficient privileges to complete a certain task
-
Normal validation problems
The above list may seem obvious to most experienced developers, but inexperienced developers tend not to plan properly.
This brings me to the question: How do I handle exceptions properly?
Try and Catch blocks.
Try, Catch and Finally Blocks
‘Try/Catch/Finally’ statements are used for structured exception handling. Structured Exception Handling is a term used to describe the process that can be followed whilst coding. The structure may be broken down as follows:
Try
You put all your code that you need to run inside the Try Block. The compiler will then attempt to execute the code inside the Try block until an exception occurs, if ever.
Catch
In the event of an exception, the Catch Block will catch the error or errors and attempt to handle them successfully. This is where you will handle your exceptions. Do not think that you can handle all the errors with one Catch statement, as you cannot. The trick is that you have to handle each exception individually, as each exception is ultimately different than the others.
Finally
A Finally block assists in cleaning up your resources and disposing of the necessary objects.
An example of a proper Try/Catch/Finally statement looks as follows:
Private Sub GenDWMCalc() 'Check If Duration Expired Try Dim DateGen As Date DateGen = CType(DateReg, Date) 'Date From Registry Select Case GenPeriodReg Case "Day(s)" 'Day(s) If DateDiff(DateInterval.Day, DateGen, Now) >= GenDurReg Then 'If Today's Date > Than Registry Date RandomAllGenie() 'Randomise End If Case "Week(s)" 'Week(s) If DateDiff(DateInterval.Day, DateGen, Now) >= (GenDurReg * 7) Then '* 7 For Week RandomAllGenie() End If Case "Month(s)" 'Month(s) If DateDiff(DateInterval.Month, DateGen, Now) >= GenDurReg Then RandomAllGenie() End If End Select Catch df As DateFormatException MessageBox.Show("Date In Wrong Format!") Catch ae As ArgumentException MessageBox.Show("Missing Arguments!") Catch ua As UnAuthorizedAccessException MessageBox.Show("You Do Not Have Sufficient Privileges For This Task!") End Try End Sub
Here, there might be a potential of three different exceptions, or more. Each exception has been handled individually – although not super-duper classy, but the point still remains that you should not handle all exceptions the same. Why?Well, look at the type of exceptions handled. There was an exception for the wrong date format, an exception for the wrong number of arguments received as well as an exception for not having appropriate privileges for this given task. Each of these exceptions vary not only by type, but in the way the particular problem should be handled, from each other.
Further Reading
Now that you know what exceptions are, and how to handle them, you may want to have a look at the next couple of articles:
- http://en.wikipedia.org/wiki/Exception_handling
- http://msdn.microsoft.com/en-us/library/dszsf989.aspx
- http://msdn.microsoft.com/en-us/library/fk6t46tz.aspx
- http://msdn.microsoft.com/en-us/library/vstudio/fk6t46tz%28v=vs.100%29.aspx
- http://www.homeandlearn.co.uk/NET/nets5p4.html
Conclusion
Today I showed you how to handle exceptions. I hope you have learned from this article and that you will put your knowledge to good use. Until next time, cheers!
There are always problems with every program that is released (known as “bugs”), and they can occur at any time. We can solve these problems easily by using a try catch block to “catch” the exception. There are different types of exceptions which can occur, such as an overflowException or a formatException. Create a new VB Console Application and name it ManagingErrors. Copy the following:
Dim x As String = Nothing Dim a As Integer = 10 Console.WriteLine("Pick a number") x = Console.ReadLine() Console.WriteLine(Convert.ToInt32(x) + a) Console.ReadLine()
This is a simple program that we have seen in other tutorials. We have two variables, one a string and another an integer, we tell the user to pick a number and then add both values together, and we use Convert.ToInt32 to convert the string data to integer. Run the program, type in 20 and you will get the answer, 30. This works without any problems, but what happens if you type in the letter K? The program will crash and you will get an error saying “Input string was not in a correct format“,which looks like this:
This is a Format Exception; now we can put in the code to prevent the crashing: Try Catch block.
Syntax
Try Catch ex As Exception End Try
Example
Try Console.WriteLine("Pick a number") x = Console.ReadLine() Console.WriteLine(Convert.ToInt32(x) + a) Catch fEx As FormatException Console.WriteLine(fEx.Message) End Try Console.ReadLine()
fEx is a local variable, and the code executes as normal; however if the user types in a letter or non-integer then the Format Exception error message will appear. The code has simply been moved to the Try Catch block. If you try running it, the error message will appear in the console window and the program won’t crash. However, there are many exceptions which can happen. Another type of exception is Overflow Exception where the number goes out of range; for example an integer has a range between -2,147,483,648 to 2,147,483,648 which is a large number, however if the program goes over this, the catch handler will not catch it. Run the program again and this time enter 214748364833 for your number. The program will crash with the error “Value was either too large or too small for an Int32“. Stop the program and return to the IDE.
Nested Catch Handlers
We can have nested catch handlers for different types of exceptions. Put this code just below that Console.WriteLine(fEx.Message):
Catch oEx As OverflowException Console.WriteLine(oEx.Message)
Now when you run the program and type 214748364833 the message will appear in the console window instead of crashing the program. There are many more exceptions which can occur, and we cannot go through all of them; the examples showed two common ones. So how would you catch any exception? In this case you just use the keyword ‘exception’. Let’s modify this code slightly:
Console.WriteLine(Convert.ToInt32(x) + a)
Change it so it looks like this:
Console.WriteLine(x + a)
Run the program and type a number (from 1 to 10), and the program should calculate as usual. Now type in a letter and watch how the program will crash with the message “Conversion from string “f” to type ‘Double’ is not valid” (f is the letter we chose for this test). None of the catch handlers handled the exception because the exception was a “InvalidCastException”. There are many more exceptions now to catch this exception. Below the overflowException, add another catch handler:
Catch ex As Exception Console.WriteLine(ex.Message)
This will catch all exceptions.
Summary
This tutorial covered how to manage errors, which will ensure your programs are robust. However, this does not mean you should write try catch statements everywhere in your code; only do so where problems are likely to go wrong. For example, if you have an email program many things can go wrong with sending email if it is not in the correct format, the password is not correct, the server is down, and so on.
Exceptions in VB.net provide a way to transfer control from one part of a program to another. VB.net Exception Handling is built upon four keywords – Try, Catch, Finally and Throw.
Table of contents
- What is Exception Handling in VB.net?
- Try Exception
- Catch Exception in VB.net
- Finally Exception
- Throw Exception
- What is Exception in VB.net?
- Syntax of Exception Handling in VB.net
- Exception Classes in VB.net
- Handling Exceptions in VB.net
- Creating User-Defined Exceptions in VB.net
- Throwing Objects in VB.net
- Summary
In order for you to test your VB.net Code provided in this lesson, you must test the code in your code editor. But if you wish to run this code online, we also have an Online Compiler in VB.net for you to test your VB.net Code for free.
Try Exception
A Try Exception in VB.net is used to keep track of a specific exception that the program might throw. And it always comes after one or more catch blocks to deal with these exceptions.
Catch Exception in VB.net
Catch Exception in VB.net is a section of code that, when a problem occurs in a program, handles the exception with an exception handler.
Finally Exception
Finally Exception in VB.net is used to execute a set of statements in a program, whether an exception has occurred.
Throw Exception
A Throw Exception in VB.net is used to throw an exception following the occurrence of a problem, as the name suggests.
What is Exception in VB.net?
An Exception in VB.net is an unwanted error that occurs during the execution of a program and can be a system exception or application exception. Exceptions are nothing but some abnormal and typically an event or condition that arises during the execution, which may interrupt the normal flow of the program.
Syntax of Exception Handling in VB.net
A method catches an exception by combining the Try and Catch keywords, presuming a block will generate an exception. The code that might cause an exception is enclosed in a Try/Catch block. Protected code is code that is contained within a Try/Catch block.
Syntax for using Try/Catch looks like the following:
Try
[ tryStatements ]
[ Exit Try ]
[ Catch [ exception [ As type ] ] [ When expression ]
[ catchStatements ]
[ Exit Try ] ]
[ Catch ... ]
[ Finally
[ finallyStatements ] ]
End Try
If your try block raises more than one exception in different circumstances, you can list down multiple catch statements to catch the various exception types.
Exception Classes in VB.net
In the .Net Framework, exceptions are represented by classes. The exception classes in .Net Framework are mainly directly or indirectly derived from the System.Exception class. Some of the exception classes derived from the System.Exception class are the System.ApplicationException and System.SystemException classes.
The System.ApplicationException class supports exceptions generated by application programs. So the exceptions defined by the programmers should derive from this class.
The System.SystemException class is the base class for all predefined system exception.
The following table provides some of the predefined exception classes derived from the Sytem.SystemException class.
Exception Class in VB.net | Description |
---|---|
System.IO.IOException | Handles I/O errors. |
System.IndexOutOfRangeException | Handles errors generated when a method refers to an array index out of range. |
System.ArrayTypeMismatchException | Handles errors generated when type is mismatched with the array type. |
System.NullReferenceException | Handles errors generated from deferencing a null object. |
System.DivideByZeroException | Handles errors generated from dividing a dividend with zero. |
System.InvalidCastException | Handles errors generated during typecasting. |
System.OutOfMemoryException | Handles errors generated from insufficient free memory. |
System.StackOverflowException | Handles errors generated from stack overflow. |
Handling Exceptions in VB.net
Try and catch blocks, a structured approach to the exception handling issues, are provided by VB.net. The main program statements and the error-handling statements are divided using these blocks.
These error handling blocks are implemented using the Try, Catch and Finally keywords.
Following is an example of throwing an exception when dividing by zero condition occurs:
Module exceptionProg
Sub division(ByVal num1 As Integer, ByVal num2 As Integer)
Dim result As Integer
Try
result = num1 num2
Catch e As DivideByZeroException
Console.WriteLine("Exception caught: {0}", e)
Finally
Console.WriteLine("Result: {0}", result)
End Try
End Sub
Sub Main()
division(25, 0)
Console.ReadKey()
End Sub
End Module
When the above code is compiled and executed, it produces the following result:
Exception caught: System.DivideByZeroException: Attempted to divide by zero.
Test your Code Here!
Creating User-Defined Exceptions in VB.net
You can create your own exceptions as well. ApplicationException is a base class from which user-defined exception classes are derived.
Example program in Creating User-Defined Exceptions in VB.net:
Module exceptionProg
Public Class TempIsZeroException : Inherits ApplicationException
Public Sub New(ByVal message As String)
MyBase.New(message)
End Sub
End Class
Public Class Temperature
Dim temperature As Integer = 0
Sub showTemp()
If (temperature = 0) Then
Throw (New TempIsZeroException("Zero Temperature found"))
Else
Console.WriteLine("Temperature: {0}", temperature)
End If
End Sub
End Class
Sub Main()
Dim temp As Temperature = New Temperature()
Try
temp.showTemp()
Catch e As TempIsZeroException
Console.WriteLine("TempIsZeroException: {0}", e.Message)
End Try
Console.ReadKey()
End Sub
End Module
When the above code is compiled and executed, it produces the following result:
TempIsZeroException: Zero Temperature found
Test your Code Here!
Throwing Objects in VB.net
You can throw an object if it is either directly or indirectly derived from the System.Exception class.
You can use a throw statement in the catch block to throw the present object as:
Throw [ expression ]
Example Program of Throwing Objects in VB.net:
Module exceptionProg
Sub Main()
Try
Throw New ApplicationException("A custom exception _ is being thrown here...")
Catch e As Exception
Console.WriteLine(e.Message)
Finally
Console.WriteLine("Now inside the Finally Block")
End Try
Console.ReadKey()
End Sub
End Module
When the above code is compiled and executed, it produces the following result:
A custom exception _ is being thrown here…
Now inside the Finally Block
Test your Code Here!
Summary
An exception refers to a problem that arises during program execution brought about by an unexpected circumstance. If you suspect that some code will generate an exception, surround it with a Try/Catch block.
The Finally block comes after the Try/Catch block and executes whether an exception is caught or not. VB.net allows us to create custom exceptions.
PREVIOUS
NEXT