Custom Error Handling

S

Steve Amey

Hi all

I want to be able to throw a custom error up the call stack. I have looked
around and it seems as though it's possible, but I can't get it to work
:blush:( Below is some sample code.

------------------------------------------------------------
Public Class MainForm
Public Sub Show Form
Try
Dim f As New Form1
f.Show
Catch Ex As MyCustomException
'// Handle the custom exception
Finally
'// Clean-up
End Try
End Sub
End Class

Public Class Form1
Public Sub New()
MyBase.New
'This call is required by the Windows Form Designer.
InitializeComponent()
'Add any initialization after the InitializeComponent() call
Try
'// Perform some stuff that might encounter an error
Catch Ex As Exception
Throw New MyCustomException '// I want to throw my exception up to
MainForm
End Try
End Sub
End Class
--------------------------------------------------------------

In the Sub New I will be getting information from a database and also doing
other things, these could result in an Exception. I want to be able to trap
the exception, and then create a new custom exception and have that thrown
up the call stack to the MainForm which would deal with it. If I try to
Throw my custom exception at the moment, the Catch Ex As MyCustomException
does not execute, if I put in a Catch Ex As Exception, then that will
execute.

How do I throw my custom object (which inherits from Exception) and then
catch that object up the call stack.

Regards,
Steve.
 
S

Steve Amey

Hiya

I have just noticed that my Custom Exception is being added in to an
Exception Object as the Inner Exception. Eg. Ex.InnerException =
MyCustomException

How woud I get my Exception to be the top most Exception? So Ex =
MyCustomException.

Regards,
Steve.
 
J

Jay B. Harlow [MVP - Outlook]

Steve,
Which version of VS.NET? With VS.NET 2003 I am not able to reproduce your
problem.

What exception are you seeing instead of MyCustomException?

I would recommend including the exception you caught as an inner exception
when you throw a new MyCustomException.

Hope this helps
Jay
 
S

Steve Amey

Hi Jay

I am using 2003, but it appears to be working now! I've lost count the
amount of times something doesn't work but suddenly does the next day :blush:)

I am having 1 more difficulty though, when I populate my custom exception I
set the properties such as Message, InnerException etc... but when the
exception is shown the message simply reads 'Error in the application'. When
I step through the code I set the properties, and I can see the module level
variables change, but the property doesn't. The Properties have to be
declared as Shadows, is this the reason the Message is not being displayed
correctly?

Here is the code for my Class:
-----------------------------------------------
Public Class MyCustomException
Inherits ApplicationException

Public Sub New(ByVal Ex As Exception)
With Me
..InnerException = Ex
..Message = Ex.Message.ToString
..Source = Ex.Source.ToString
..StackTrace = Ex.StackTrace.ToString
..TargetSite = Ex.TargetSite
..HelpLink = Ex.HelpLink
End With
End Sub

Public Sub New(ByVal Ex As Exception, ByVal dataSet As DataSet)
With Me
..InnerException = Ex
..Message = Ex.Message.ToString
..Source = Ex.Source.ToString
..StackTrace = Ex.StackTrace.ToString
..TargetSite = Ex.TargetSite
..HelpLink = Ex.HelpLink
..DataSet = dataSet
End With
End Sub

Public Shadows Property InnerException() As Exception
Get
Return m_InnerException
End Get
Set(ByVal Value As Exception)
m_InnerException = Value
End Set
End Property

Public Overrides Property Source() As String
Get
Return m_Source
End Get
Set(ByVal Value As String)
m_Source = Value
End Set
End Property

Public Shadows Property Message() As String
Get
Return m_Message
End Get
Set(ByVal Value As String)
m_Message = Value
End Set
End Property

Public Shadows Property TargetSite() As Reflection.MethodBase
Get
Return m_TargetSite
End Get
Set(ByVal Value As Reflection.MethodBase)
m_TargetSite = Value
End Set
End Property

Public Shadows Property StackTrace() As String
Get
Return m_StackTrace
End Get
Set(ByVal Value As String)
m_StackTrace = Value
End Set
End Property

Public Shadows Property HelpLink() As String
Get
Return m_HelpLink
End Get
Set(ByVal Value As String)
m_HelpLink = Value
End Set
End Property

Public Property DataSet() As DataSet
Get
Return m_oDataSet
End Get
Set(ByVal Value As DataSet)
m_oDataSet = Value
End Set
End Property

End Class
-----------------------------------------------------

So when I read the MyCustomException.Message property, it doesn't return the
value in m_Message but returns the text I described above.

Regards,
Steve
 
J

Jay B. Harlow [MVP - Outlook]

Steve,
The Properties have to be
declared as Shadows, is this the reason the Message is not being displayed
correctly?
Correct.

You should not Shadow base class members! Shadows is used primarily for
version control. For example: You release version one of your
MyCustomException with a specific method, MS release .NET 2.0 with the same
method in System.ApplicationException, Shadows is used in this case to allow
you to continue using your method, while the base class can use its own
version of the method.

I was suggesting you pass the exception you caught to the base constructor:

Optionally I would allow users of the exception to specify a Message, and
not specify the innerException, something like:

Public Class MyCustomException
Inherits ApplicationException

Private ReadOnly m_dataSet As DataSet

Public Sub New()
MyClass.New(Nothing, Nothing, Nothing)
End Sub

Public Sub New(ByVal message As String)
MyClass.New(message, Nothing, Nothing)
End Sub

Public Sub New(ByVal innerException As Exception)
MyClass.New(Nothing, innerException, Nothing)
End Sub

Public Sub New(ByVal dataSet As DataSet)
MyClass.New(Nothing, Nothing, dataSet)
End Sub

Public Sub New(ByVal message As String, ByVal innerException As
Exception)
MyClass.New(message, innerException, Nothing)
End Sub

Public Sub New(ByVal message As String, ByVal dataSet As DataSet)
MyClass.New(message, Nothing, dataSet)
End Sub

Public Sub New(ByVal innerException As Exception, ByVal dataSet As
DataSet)
MyClass.New(Nothing, innerException, dataSet)
End Sub

Public Sub New(ByVal message As String, ByVal innerException As
Exception, ByVal dataSet As DataSet)
MyBase.New(message, innerException)
m_dataSet = dataSet
End Sub

Public ReadOnly Property DataSet() As DataSet
Get
Return m_dataSet
End Get
End Property

End Class

NOTE: The MyClass.New allows you to call another constructor on the same
class, while MyBase.New allows you to call a base constructor. I chain all
the constructors into one common constructor, then this common constructor
calls the base constructor. I do not show the special constructor required
for serialization.

The following article provides some good information on creating custom
Exception classes.

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dncscol/html/csharp08162001.asp

The example are in C#, however they should be easy enough to convert to
VB.NET.

Hope this helps
Jay
 
J

Jay B. Harlow [MVP - Outlook]

Steve,
I should add, you can override either (or both) the Exception.Message
property & Exception.ToString, if you want to include details from the
dataset, when Exception.Message is displayed or Exception.ToString is used.

Normally I use Exception.Message when I am displaying the exception to the
user, while I use Exception.ToString when I am logging the exception in my
Global Exception Handler.

Hope this helps
Jay
 
S

Steve Amey

Hi Jay

Thank you very much for your help, it's much appreciated!

Kind Regards,
Steve
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top