School Assignment? Project Due Tomorrow? Chat LIVE With A Programming Expert!

Welcome to Dream.In.Code
Become an Expert!

Join 307,099 Programmers for FREE! Get instant access to thousands of experts, tutorials, code snippets, and more! There are 2,033 people online right now. Registration is fast and FREE... Join Now!




Error handling - Part three.

 
Reply to this topicStart new topic

> Error handling - Part three., Throwing, creating, piling and presenting exceptions.

Rating  5
jens
Group Icon



post 6 Mar, 2009 - 03:54 PM
Post #1


VB.NET: Error handling - Part three, more on structured error handling.

A tutorial on error handling in VB.NET. This - part three - is about somewhat more advanced structured error handling.

It's kind of a boring subject, I want to code, to make fantastic programs that solve some kind of problem or do funny things. I'm not really interested in errors. But them buggers pop up every now and then and destroy the beautiful experience of using my programs. smile.gif So I want to learn how to take care of them in a good way.

This error handling tutorial keeps growing. I didn't know there was so much when I started on it. I hope someone is helped somewhat by it - at least I'm really learning. wink2.gif I'm writing this as I've finished the Inner exceptions part and I'm sorry I got a little tired towards the end. The facts are there and they are explained but not in so much detail maybe. Anyway here we go... smile.gif

1) Throwing errors - working at two levels.
2) Your very own exception class, in my case the JensError smile.gif
3) Inner exceptions - the original error.
4) A error information routine; informing the user in a consistent way.


1) Throwing errors - working at two levels.

By now I assume you feel confident with code like this:
vb

Option Explicit On
Option Strict On

Public Class Form1

Private Sub HandledError1()
Dim test As Short

Try
test = 16000
test *= test
Catch ex1 As IndexOutOfRangeException
MsgBox("We caught an Index out of range exception in the sub: " & vbCrLf & ex1.ToString)
'Catch ex2 As Exception
' MsgBox("Caught an unspecified error in the sub: " & vbCrLf & ex2.ToString)
' Exit Sub
Finally
MsgBox("In finally.")
End Try
MsgBox("After Try - Catch")
End Sub

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Try
HandledError1()
Catch ex1 As OverflowException
MsgBox("We caught an overflow exception in the calling code: " & vbCrLf & ex1.ToString)
End Try
End Sub

End Class

If not, please review part two of the tutorial.

When you have caught an error it is "used up", that's what I wrote earlier. That statement wasn't exactly true... Run the following code, uncomment the line Throw ex1 and run it again, notice what happens.
vb

Option Explicit On
Option Strict On

Public Class Form1

Private Sub HandledError1()
Dim test As Short
Dim appErr As New ApplicationException

Try
test = 16000
test *= test
Catch ex1 As Exception
MsgBox("Caught an unspecified error in the sub: " & vbCrLf & ex1.ToString)
'Throw ex1
'Throw appErr 'Throwing another error - an ApplicationException error.
Finally
MsgBox("In finally.")
End Try
MsgBox("After Try - Catch")
End Sub

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Try
HandledError1()
Catch ex1 As Exception
MsgBox("We caught an exception in the calling code: " & vbCrLf & ex1.ToString)
End Try
End Sub

End Class


The Throw ex1 works like a Exit Sub but also generates an error that can be used later. If you want to you can Throw some other error. You decide what error you want to throw. You can re-throw the original error or throw a new error - like we do above - or even throw your own error (see below)!


2) Your very own exception class, in my case the JensError smile.gif

Let's step things up at bit.
About now I think we leave the beginners error handling... Run the following code.
vb

Option Explicit On
Option Strict On

Public Class Form1

Private Sub HandledError1()
Dim test As Short
'Create a new error object and a variable to hold it.
Dim myError As New JensError(" *** A JensError from the sub HandledError. *** ")
Try
test = 16000
test *= test
Catch ex1 As Exception
'Try uncommenting either or both these MsgBox lines. It will give you
'a feel for how errors are presented to the user.
MsgBox("Caught an unspecified error in the sub: " & vbCrLf & ex1.Message)
'MsgBox("Caught an unspecified error in the sub: " & vbCrLf & ex1.ToString)

'Try uncommenting one of the below rows at a time.
'Think of the result and contemplate the code...
Throw myError
'Throw ex1
Finally
MsgBox("In finally.")
End Try

MsgBox("After Try - Catch")
End Sub

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Try
HandledError1()
Catch ex1 As JensError
MsgBox("We caught a JensError in the calling code: " & vbCrLf & ex1.ToString)
ex1.Talk()
Catch ex2 As Exception
MsgBox("We caught an exception in the calling code: " & vbCrLf & ex2.ToString)
End Try
End Sub

End Class


Public Class JensError : Inherits Exception
'This is a new class. This class is a home made kind of Exception.
'Since it inherits the class Exception it does have all the methods
'and properties that class Exception has. But it also has some
'special functionality and a special name - maybe that is the most
'useful part. E.g. if you develop your own communications driver
'you can throw your own special errors from it. Then the developer
'using your driver can easily distinguish between errors from your
'driver (a time out maybe) and other errors.
'Note that this class does not handle all methods supported by the
'base class Exception.

#Region "Calls to base class constructors (The 'New' in the Exception Class)"
'This constructor is here to make sure that you can create an error
'object without any arguments. As soon as we create a constructor the
'default no-arg-constructor is inhibited so we have to make our own.
'This only calls the no-arg-constructor of the Exception Class.
Public Sub New()
MyBase.New()
End Sub

'Again, this is here just to ensure that we can handle creation of
'an error object with only a message as parameter. This exists in
'the Exception class but is inhibited as we make an Exception of
'our own.
Public Sub New(ByVal msg As String)
MyBase.New(msg)
End Sub

#End Region

'You can add your own methods to your own Exception Class.
'This function is also just an example but it shows that you
'can put your own stuff in your own exception class.
'This could be used in a lot of ways.
Public Sub Talk()
'Here you can put whatever functionality you want.
MsgBox("A JensError")
End Sub

End Class#End Region

'You can add your own methods to your own Exception Class.
'This function is also just an example but it shows that you
'can put your own stuff in your own exception class.
'This could be used in a lot of ways.
Public Sub Talk()
'Here you can put whatever functionality you want.
MsgBox("A JensError")
End Sub

End Class


Woohaaa...! No, wait! It's not that bad - really. smile.gif
First of all, the latter part of the code is a new class and most of that class is just comments. The class is a kind of Exception. I've inherited the class Exception to make my own Exception class - the JensError. Read the comments to get an idea why you'd want to do such a thing.

What's new is the new class and that I make an JensError exception object of it on the row Dim myError As New JensError(" *** A JensError from the sub HandledError. *** ") calling it myError. Then I throw this special exception when I catch another exception - just for the hell of it. No, really, it's to demonstrate that you can do stuff like that.

Then in the calling code (in Form1_Load) I check for JensError exceptions and in case I find one I use a special method that is present only in JensError exceptions. Then I'm done. smile.gif Great isn't it! You can do a lot of wonderful things with exceptions, exception handling and your own exception classes. Bet you could make a whole program just by throwing exceptions around. biggrin.gif

But really. Try the code, comment out and uncomment parts. Pay heed to what happens and read the comments in the code. Then make yourself a nice cup of tea (or whatever), have a break, think of somthing else and be back soon.

Tea time...


3) Inner exceptions - the original error.

Ok, you saw what I did above. I caught an error and threw another error, the JensError exception. Great, fine, but what if you want to know what the original error was too? Of course there's a way...
Run the following, commenting out and uncommenting according to the comments.
vb

Option Explicit On
Option Strict On

Public Class Form1

Private Sub HandledError1()
Dim test As Short
'Create a new error object and a variable to hold it.
Dim myError As New JensError(" *** A JensError from the sub HandledError. *** ")
'This only creates a variable, no object.
'I might not want to run the constructor of the err object yet.
'(More on this below)
Dim myError2 As JensError
Try
test = 16000
test *= test
Catch ex1 As Exception
MsgBox("Caught an unspecified error in the sub: " & vbCrLf & ex1.Message)
'
'Note that when the below line of code is executed you'll get the
'message "Now we are in one of the constructors of the JensError class."
'from the constructor of the JensError class below.
myError2 = New JensError("Original error as a parameter. ", ex1)
'Try uncommenting one of the below rows at a time.
'Think of the result while contemplating the code...
Throw myError2
'Throw myError
'Throw ex1
Finally
MsgBox("In finally.")
End Try

MsgBox("After Try - Catch")
End Sub

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Try
HandledError1()
Catch ex1 As JensError
MsgBox("We caught a JensError in the calling code: " & vbCrLf & ex1.ToString)
ex1.Talk()
Catch ex2 As Exception
MsgBox("We caught an exception in the calling code: " & vbCrLf & ex2.ToString)
End Try
End Sub

End Class


Public Class JensError : Inherits Exception

#Region "Calls to base class constructors (The 'New' in the Exception Class)"
Public Sub New()
MyBase.New()
End Sub

Public Sub New(ByVal msg As String)
MyBase.New(msg)
End Sub

'Here, first we use the Exception Class constructor to properly
'initialize everything that is common between the Exception Class
'and our JensError Class. Then we have some special functionality
'in our class, namely showing a message box.
'This is only an example but it shows some of what you can do with
'your own exception class and som of the things you have to do
'with your own exception class. This will show the message
'"Now we are in one of the constructors of the JensError class."
'when the JensError object is created, NOT when you use it!
Public Sub New(ByVal msg As String, ByVal err As Exception)
MyBase.New(msg, err)
MsgBox("Now we are in one of the constructors of the JensError class.")
End Sub
#End Region

Public Sub Talk()
'Here you can put whatever functionality you want.
MsgBox("A JensError")
End Sub

End Class


First, note that the appErr is initialized with a message and the original exception. This will give an error message that consists - amongst other things - of your thrown error (the ApplicationException), your message and the original error.

Then you try the different Throw-statements and nothing new happens until you get to the myError2 = New JensError("Original error as a parameter. ", ex1) and the Throw myError2 which has to be uncommented at the same time.

In the JensError class I've added one more constructor that takes care of when you want to use a message and the original error. In that constructor I included a messagebox to show when the constructor is used. Try commenting out only the row Throw myError2 and you'll still get the messagebox. Also note that it's not when you Dim myError2 As JensError that the constructor is executed.


If you've followed me this far, experimented with the code, read it, read the comments and my text I hope you've got a good grip on Throwing errors, making your own exception classes, handling inner exceptions and at the same time got a glimpse on constructors - especially in exception classes. You should also have been somewhat acquinted with inheritance, pertaining to the Exception class anyway.

If not, read again, still not? Please comment and I'll try to update the tutorial or explain more.


4) A error information routine; informing the user in a consistent way.

All of this error handling stuff has two purposes:
To spare the user from ugly errors while trying to recover and dying gracefully if you can't recover.

One small step in the quest of keeping the user happy is to present a nicly formatted error dialog.
CODE

Option Explicit On
Option Strict On

Public Class Form1

    Private Function UserInteractionOnError(ByVal codePos As String, ByVal err As Exception) As Boolean
        Dim msgText As String

        msgText = "An error occurred in the program at: " & vbCrLf & codePos & vbCrLf
        msgText = msgText & "The error was: " & vbCrLf & err.Message & vbCrLf & vbCrLf
        msgText = msgText & "Take note of the above message." & vbCrLf
        msgText = msgText & "Do you want to try to save your work before restarting the program?"
        Return (MsgBox(msgText, CType(20, MsgBoxStyle), "Program in trouble...") = 6)

    End Function

    Private Sub HandledError1()
        Dim test As Short
        Try
            test = 16000
            test *= test
        Catch ex1 As Exception
            If Not UserInteractionOnError("HandledError1: test *= test", ex1) Then Application.Exit()
        Finally
            MsgBox("Cleaning up in finally.")
        End Try

        MsgBox("Resuming the execution of the program")
    End Sub

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Try
            HandledError1()
        Catch ex1 As Exception
            MsgBox("We caught an exception in the calling code: " & vbCrLf & ex1.ToString)
        End Try
    End Sub

End Class

The idea here is that you use the If Not UserInteractionOnError ...Then... in all your Catch blocks in order to make sure the user isn't surprised. It's just a nice touch.


This concludes my error handling tutorial.

Regards
/Jens

PS: I would very much like some comments on this tutorial. If you didn't like it I'd be happy to hear any suggestions to improve it. Thank you.
PPS: If you want to learn real hard core custom error handling take a look at this from PsychoCoder.

This post has been edited by jens: 6 Mar, 2009 - 04:19 PM
Go to the top of the page
+Quote Post


Register to Make This Ad Go Away!


Fast ReplyReply to this topicStart new topic
1 User(s) are reading this topic (1 Guests and 0 Anonymous Users)
0 Members:

 


Lo-Fi Version Time is now: 11/21/09 12:10PM

Live Help!

Be Social

Dream.In.Code RSS Feed Dream.In.Code LinkedIn Group Follow Us On Twitter Fan Us On Facebook

Tutorials

Programming

Web Development

Reference Sheets

Code Snippets

DIC Chatroom

Bye Bye Ads

Monthly Drawing

Thumb Drive

Top Contributors

Top 10 Kudos This Month