Page 1 of 1

Custom Structured Exception Handling in VB.Net Rate Topic: ***** 1 Votes

#1 PsychoCoder  Icon User is offline

  • Google.Sucks.Init(true);
  • member icon

Reputation: 1632
  • View blog
  • Posts: 19,853
  • Joined: 26-July 07

Post icon  Posted 09 December 2007 - 10:01 PM

Welcome to my tutorial on Custom (Structured) Exception handling in VB.Net (C# version coming soon). In this tutorial we will look into at creating a Class Library to help with dealing with exception handling in a custom way.

As a developer all of us have the same goal, to write error free applications, but the chances of that are about the same as finding Bigfoot. As we all know, the end user will always find a way to break our applications, in ways we never thought of in the first place. We can ask them "What were doing when the error happened" and, across the board, the answer is always "I don't know." Then our next question, like we're trained robots, is "What did the error say", and we always get something from "It said something like <insert meaningless statement here>.", or "I'm not sure, I just clicked the OK button and tried to finish, great help huh.

Most applications give basic Microsoft designed and generated messages, like the one pictured below:

Attached Image

This kind of message is enough to scare most end users from ever using that application again, doesn't do much for customer loyalty. So I spent hours and hours thinking that there has to be a better way of handling exceptions that inevitably happen, no one is the "perfect" programmer, except for maybe Martyr2 :P . All the .Net classes derive from the SystemException, but it also provides the ApplicationException. It is Microsoft's "Best Practices" to inherit from the ApplicationException class rather then the SystemException when writing your own exception handling class.

Before asking, or stating your personal opinion, this is a discussion that has been raging for years and may never end, so I suggest you go with what you feel comfortable, I choose to inherit from System.Exception because thats how I feel comfortable. So now lets get into our Class Library for our own structured custom exception handling, bear in mind this is a long tutorial as there just isnt any shortcut to accomplish this.

First thing you need, as with all classes you create, you ned to add and inherit the particular Namespaces you need to accomplish the tasks of your class, in this case our custom exception handling, so now the Namespaces:

Imports System.Configuration
Imports System.Runtime
Imports System.Runtime.Serialization
Imports System.Environment
Imports System.Diagnostics
Imports System.IO
Imports System



You will notice as we get into this class we have used the <Serializable()> , meaning this class can be Serialized, meaning it can be populated once and pass it from object to object without having to repopulate it, just deserialize it when you need to.

An exception has many, many properties, and as you know, when creating properties, whether they be ReadOnly or Read/Write, they all need their own variable, so now we're going to look at the variables we need for our Class Library, many which are instantiated once declared:

#Region "Variables Declarations"
	Private _methodName As String
	Private _version As String = "0.0"
	Private _methodAction As String = "Unknown"
	Private _culture As String = "Unknown"
	Private _user As String = System.Environment.UserName
	Private _hostMachine As String = System.Environment.MachineName
	Private _osVersion As String = System.Environment.OSVersion.ToString
	Private _exceptionDate As Date = Now.ToString("yyyy/MM/dd")
	Private _exceptionTime As DateTime = Now.ToShortTimeString
	Private _exceptionType As String
	Private _hasInner As Boolean = False
	Private _hasCulture As Boolean
	Private _hasVersion As Boolean
	Private _exceptionLevel As String = "Unknown"
	Private _message As String = "Unknown"
	Private _stackTrace As String = "Unknown"
#End Region



NOTE: You will once again notice I break my class files into different sections using the Region Keyword, this, in my opinion, makes it easier to find thing in a large class file, such as this one. This, of course, is a design decision of all developers.

Next thing we're going to look at are the properties themselves. In this class there are 16 variables, 15 ReadOnly and 1 Read/Write. We have the ReadOnly variables because this information comes straight from the Exception being trapped so theres no need to allow the developer to set them. The single Read/Write variable allows the developer to add text describing what they were doing in the method that caused the Exception to happen in the first place. First we will look at the ReadOnly, and this is information that can be extracted directly from the Exception itself:

#Region " Exception Type "
	''' -----------------------------------------------------------------------------
	''' <summary>
	''' Property to hold the exception type
	''' </summary>
	''' <remarks>
	''' </remarks>
	''' <history>
	''' 	[richard.mccutchen]	8/06/05	Created
	''' </history>
	''' -----------------------------------------------------------------------------
	Public ReadOnly Property ExceptionType() As String
		Get
			Return GetBaseException.ToString.Substring(0, GetBaseException.ToString.IndexOf(":"))
		End Get
	End Property
#End Region

#Region " Application Culture "
	''' -----------------------------------------------------------------------------
	''' <summary>
	''' Property to hold the applications culture
	''' </summary>
	''' <value></value>
	''' <remarks>
	''' </remarks>
	''' <history>
	''' 	[richard.mccutchen]	8/06/05	Created
	''' </history>
	''' -----------------------------------------------------------------------------
	Public ReadOnly Property ApplicationCulture() As String
		Get
			If _hasCulture = False Then
				GetAttributes()
			End If
			Return _culture
		End Get
	End Property
#End Region

#Region " Application Version "
	''' -----------------------------------------------------------------------------
	''' <summary>
	''' Property to hold the Applications version
	''' </summary>
	''' <value></value>
	''' <remarks>
	''' </remarks>
	''' <history>
	''' 	[richard.mccutchen]	8/06/05	Created
	''' </history>
	''' -----------------------------------------------------------------------------
	Public ReadOnly Property ApplicationVersion() As String
		Get
			If _hasVersion = False Then
				GetAttributes()
			End If
			Return _version
		End Get
	End Property
#End Region

#Region " ApplicationName "
	Public ReadOnly Property ApplicationName() As String
		Get
			_methodName = MyBase.Source
			Return _methodName
		End Get
	End Property
#End Region

#Region " Error Date "
	''' -----------------------------------------------------------------------------
	''' <summary>
	''' Property to hold the date of the exception
	''' </summary>
	''' <value></value>
	''' <remarks>
	''' </remarks>
	''' <history>
	''' 	[richard.mccutchen]	8/06/05	Created
	''' </history>
	''' -----------------------------------------------------------------------------
	Public ReadOnly Property ExceptionDate() As String
		Get
			Return _exceptionDate
		End Get
	End Property
#End Region

#Region " Error Time "
	''' -----------------------------------------------------------------------------
	''' <summary>
	''' Property to hold the time of the exception
	''' </summary>
	''' <value></value>
	''' <remarks>
	''' </remarks>
	''' <history>
	''' 	[richard.mccutchen]	8/06/05	Created
	''' </history>
	''' -----------------------------------------------------------------------------
	Public ReadOnly Property ExceptionTime() As String
		Get
			Return _exceptionTime
		End Get
	End Property
#End Region

#Region " Machine Name "
	''' -----------------------------------------------------------------------------
	''' <summary>
	''' Property to hold the name of the machine the exception occurred on
	''' </summary>
	''' <value></value>
	''' <remarks>
	''' </remarks>
	''' <history>
	''' 	[richard.mccutchen]	8/06/05	Created
	''' </history>
	''' -----------------------------------------------------------------------------
	Public ReadOnly Property HostMachine() As String
		Get
			Return _hostMachine
		End Get
	End Property
#End Region

#Region " Object Method "
	''' -----------------------------------------------------------------------------
	''' <summary>
	''' Property to hold the method that caused the exception
	''' </summary>
	''' <value></value>
	''' <remarks>
	''' </remarks>
	''' <history>
	''' 	[richard.mccutchen]	8/06/05	Created
	''' </history>
	''' -----------------------------------------------------------------------------
	Public ReadOnly Property MethodName() As String
		Get
			Return MyBase.TargetSite.Name
		End Get
	End Property
#End Region

#Region "OS Version"
	''' -----------------------------------------------------------------------------
	''' <summary>
	''' Property to hold the OS of the machine where the exception occurred
	''' </summary>
	''' <value></value>
	''' <remarks>
	''' </remarks>
	''' <history>
	''' 	[richard.mccutchen]	8/06/05	Created
	''' </history>
	''' -----------------------------------------------------------------------------
	Public ReadOnly Property OSVersion() As String
		Get
			Return _osVersion
		End Get
	End Property
#End Region

#Region " Inner Exception "
	''' -----------------------------------------------------------------------------
	''' <summary>
	''' Property to hold the inner exception (if exists)
	''' </summary>
	''' <value></value>
	''' <remarks>
	''' </remarks>
	''' <history>
	''' 	[richard.mccutchen]	8/06/05	Created
	''' </history>
	''' -----------------------------------------------------------------------------
	Public ReadOnly Property AppInnerException() As String
		Get
			If _hasInner Then
				Dim pos As Integer = MyBase.InnerException.ToString.IndexOf(":")

				Return MyBase.InnerException.ToString.Substring(0, pos)
			Else
				Return String.Empty
			End If
		End Get
	End Property
#End Region

#Region " StackTrace "
	''' -----------------------------------------------------------------------------
	''' <summary>
	''' Property to hold the stacktrace of the exception
	''' </summary>
	''' <value></value>
	''' <remarks>
	''' </remarks>
	''' <history>
	''' 	[richard.mccutchen]	8/06/05	Created
	''' </history>
	''' -----------------------------------------------------------------------------
	Public Overrides ReadOnly Property StackTrace() As String
		Get
			If Not _hasInner Then
				_stackTrace = MyBase.StackTrace
			Else
				If Not Me.InnerException Is Nothing Then
					_stackTrace = Me.InnerException.StackTrace
				Else
					_stackTrace = String.Empty
				End If
			End If
			Return _stackTrace
		End Get
	End Property
#End Region

#Region " User Name "
	''' -----------------------------------------------------------------------------
	''' <summary>
	''' Property to hold the username of the person
	''' logged into the machine where the exception occurred
	''' </summary>
	''' <value></value>
	''' <remarks>
	''' </remarks>
	''' <history>
	''' 	[richard.mccutchen]	8/06/05	Created
	''' </history>
	''' -----------------------------------------------------------------------------
	Public ReadOnly Property UserName() As String
		Get
			Return _user
		End Get
	End Property
#End Region



Two of the properties, ApplicationCulture and ApplicationVersion both call functions, we will get to these functions later, then the properties will make more sense on how they're populated. The Read/Write property is the only that allows the developer to interject his own text into the exception object, something currently not available in the current .Net Exception Object:

#Region "Object Method Action"
	''' -----------------------------------------------------------------------------
	''' <summary>
	''' Property to hold what the method was accomplishing when the exception occurred
	''' </summary>
	''' <value></value>
	''' <remarks>
	''' Can also be used for developer comments and trace logging
	''' </remarks>
	''' <history>
	''' 	[richard.mccutchen]	8/06/05	Created
	''' </history>
	''' -----------------------------------------------------------------------------
	Public Property MethodAction() As String
		Get
			Return _methodAction
		End Get
		Set(ByVal value As String)
			If Not String.IsNullOrEmpty(value) Then
				_methodAction = value
			Else
				_methodAction = _methodName
			End If
		End Set
	End Property
#End Region



Next thing we're going to look at is the Constructors of our Class Library class. Most classes need constructors in order to be initialized. In this class we have 6 constructors. 3 are recommended by Microsoft, the other 3 utilize items such as SerializationInfo and StreamingContext, which are used for deserializing Exception.

Instead of showing all 6 at once, Ill show the Standardconstructors, then the Custom constructors. First the Standard:

#Region " Standard Constructors "
	'***************************************************************************************
	'	   Standard constructions that are recommended by Microsoft when inheriting from
	'	   the ApplicationException Class
	'***************************************************************************************
	Public Sub New()
		MyBase.New()
		Me.Clear()
	End Sub

	Public Sub New(ByVal message As String)
		MyBase.New(message)
		Me.Clear()
	End Sub

	Public Sub New(ByVal message As String, ByVal innerException As Exception)
		MyBase.New(message, innerException)
		Me.Clear()
		_hasInner = True
	End Sub
#End Region



If you notice, those are pretty standard constructors for an Exception class, now we look at the Custom constructors and they will seem to be somewhat different than the Standard once:

#Region " Custom Constructors "
	'***************************************************************************************
	'	   Standard constructions utilizing items such as the methods action (what was the
	'	   method doing when the exception occurred), and SerializationInfo & StreamingContext
	'	   for deserializing an exception
	'***************************************************************************************

	Public Sub New(ByVal methodAction As String, ByVal message As String)
		MyBase.New(message)
		_methodAction = methodAction
	End Sub

	Public Sub New(ByVal methodAction As String, ByVal message As String, ByVal innerException As Exception)
		MyBase.New(message, innerException)
		_methodAction = methodAction
		_hasInner = True
	End Sub

	Public Sub New(ByVal info As SerializationInfo, ByVal context As StreamingContext)
		MyBase.New(info, context)
		_culture = info.GetString("ApplicationCulture")
		_version = info.GetString("ApplicationVersion")
		_hasCulture = info.GetBoolean("ApplicationCultureFlag")
		_hasVersion = info.GetBoolean("ApplicationVersionFlag")
		_methodAction = info.GetString("MethodAction")
		_hostMachine = info.GetString("MachineName")
		_user = info.GetString("UserName")
		_osVersion = info.GetString("OSVersion")
		_exceptionDate = info.GetDateTime("ErrorDate")
		_exceptionTime = info.GetString("ErrorTime")
		_exceptionLevel = info.GetString("ExceptionLevel")
		_methodName = info.GetString("ApplicationName")
		_exceptionType = info.GetString("ExceptionType")
		_stackTrace = info.GetString("StackTrace")
	End Sub
#End Region



These are the constructors that allow the developer to interject his own words on what he has doing in the method when the exception occurred. Now we can get into the meat of our Exception handler, we can discuss the methods that actually make it work. The first method we will be looking at will allow us to get the base exception of an exception. In the hierarchal listing of exceptions, there can be an exception, but 3 levels down there lies the exception that actually caused the exception in the first place. So lets take a look at that method:

#Region " GetBase Exception "
	''' <summary>
	''' Function to retrieve the base exception in string format
	''' </summary>
	''' <returns>The base exception type</returns>
	''' <remarks></remarks>
	Public Overrides Function GetBaseException() As Exception
		Return MyBase.GetBaseException()
	End Function
#End Region



Here we Override the http://msdn2.microso...etBaseException. Overriding this in our class is what allows us to reach the Exception that was at the root of the Exception thrown. The next method we will be looking at is the ToString()[/ur] Method. But in our class we will re overriding it so we can have the items we wish to have regarding the exception wee just trapped in it. Lets say that at the end of your code you have MessageBox.Show(ex.ToString()), it would contains all the Exception information we want since we over rote the base method, it looks something like this:

#Region " To String "
	''' <summary>
	''' Override the base ToString function to return the exception details 
	''' in a our structured exception handling object
	''' </summary>
	''' <returns>The exception details in a comma delimited string</returns>
	''' <remarks></remarks>
	Public Overrides Function ToString() As String
		'Return MyBase.ToString & vbCrLf & _
		Return "Source Object : " & Me.Source & "," & _
			   "Source Method : " & MethodName & "," & _
			   "Method Action : " & _methodAction & "," & _
			   "Stack Trace : " & StackTrace & "," & _
			   "Inner Exception : " & AppInnerException & "," & _
			   "Base Excception : " & ExceptionType & "," & _
			   "Date : " & _exceptionDate & "," & _
			   "Time : " & _exceptionTime & "," & _
			   "Application Name : " & MyBase.Source.ToString & "," & _
			   "Application Version : " & _version & "," & _
			   "Application Culture : " & _culture & "," & _
			   "Username : " & _user & "," & _
			   "Machine Name : " & _hostMachine & "," & _
			   "OS Version : " & _osVersion
	End Function
#End Region



Notice here we take all the items we wish to have in the ToString() method, and have them in a comma delimited string, which we can parse at a later date if we chose to. The next method we have, which we over wrote as well, is call GetObjectData, which we use to serialize out Exception Object. We over write this method so we can add the items we wish to have in our serialized Exception object. Here we use the
SerializationInfo Class to add all the data we have collected about out Exception to the Serialized object:

#Region " GetObjectData() "
	''' <summary>
	''' Procedure for getting the information about the exception so the object
	''' can be serialized
	''' </summary>
	''' <param name="info">Data to serialize/deserialize an object (In this case an Exception)</param>
	''' <param name="context">Object to contains the source of a given serialized stream</param>
	''' <remarks></remarks>
	Public Overrides Sub GetObjectData(ByVal info As SerializationInfo, ByVal context As StreamingContext)
		MyBase.GetObjectData(info, context)
		'Add the items of the exception to the SerializationInfo cache for serialization
		info.AddValue("ApplicationCulture", _culture)
		info.AddValue("ApplicationVersion", _version)
		info.AddValue("ApplicationCultureFlag", _hasCulture)
		info.AddValue("ApplicationVersionFlag", _hasVersion)
		info.AddValue("MethodAction", _methodAction)
		info.AddValue("MachineName", _hostMachine)
		info.AddValue("UserName", _user)
		info.AddValue("OSVersion", _osVersion)
		info.AddValue("ErrorDate", _exceptionDate)
		info.AddValue("ErrorTime", _exceptionTime)
		info.AddValue("ExceptionLevel", _exceptionLevel)
		info.AddValue("ApplicationName", _methodName)
		info.AddValue("ExceptionType", _exceptionType)
		info.AddValue("StackTrace", _stackTrace)
	End Sub
#End Region



The next, and ;ast 4 methods, are the main ones, they're the ones we're using to actually use Reflection to dig as deep into the Exception object we have acquired to get all the information we can find, some of the information being the application version, and the application culture. The first method we'll look at is called GetAttributes, and this method drills down as deep as it can into the [url="http://msdn2.microsoft.com/en-us/library/system.type.assemblyqualifiedname.aspx"]AssemblyQualifiedName to get as much information as possible before calling the GetAppInfo method:

#Region " GetAttributes() "
	''' <summary>
	''' Procedure to retrieve the qualified name of
	''' the assembly for the application that caused the exception.
	''' With this information we can get the culture, version and
	''' more of the application with the exception
	''' </summary>
	''' <remarks>
	''' This method uses the ReflectedType method to retrieve the assemblies information
	''' which is contained in the AssemblyQualifiedName. First it checks if theres an inner
	''' exception and gets the assembly information based on the inner exception
	'''</remarks>
	Private Sub GetAttributes()
		If _hasInner Then
			If Not Me.TargetSite Is Nothing Then
				If Not Me.TargetSite.ReflectedType Is Nothing Then
					If Not Me.TargetSite.ReflectedType.AssemblyQualifiedName Is Nothing Then
					   >> GetAppInfo(Me.TargetSite.ReflectedType.AssemblyQualifiedName)
					End If
				End If
			End If
		Else
			If Not Me.InnerException Is Nothing Then
				If Not Me.InnerException.TargetSite Is Nothing Then
					If Not Me.InnerException.TargetSite.ReflectedType Is Nothing Then
						If Not Me.InnerException.TargetSite.ReflectedType.AssemblyQualifiedName Is Nothing Then
						  >>  GetAppInfo(Me.InnerException.TargetSite.ReflectedType.AssemblyQualifiedName)
						End If
					End If
				End If
			End If
		End If
		_exceptionDate = Now.Date
		_exceptionTime = System.DateTime.Today.ToShortTimeString
	End Sub
#End Region



In all of that code you will notice the >>, this is where it is calling this method. This methods main function is to retrieve the applications culture and version from the assembly. When I first write this Class Library last year this was one ugly method, so in time I have re factored it ti make it more readable. This method parses and splits looking for 2 main keywords Version, and Culture. So, lets take a look at the new re factored version:

#Region " GetAppInfo "
	''' <summary>
	''' Procedure for retrieving the application culture and version
	''' </summary>
	''' <param name="assembly">
	''' The string returned from GetApplicationAttributes
	''' which retrieves the assembly information for the calling application
	''' </param>
	''' <remarks></remarks>
	Private Sub GetAppInfo(ByVal assembly As String)
		'Create a string array based on the assembly string provided
		Dim assemblyValue() As String = Split(assembly)
		'Loop through each item in the string array
		For Each item As String In assemblyValue
			'Check to see if _bVersion is true or false
			If _hasVersion = False Then
				'Since its false we need to check the current index
				'of the string array for the word "Version"
				If item.IndexOf("Version", 0) >= 0 Then
					'Since it contains the work "Value" we pass it t
					'our GetVersion function to parse the string
					'and return the version from it
					_version = >> GetVersion(item)
					'Set _bVersion to true
					_hasVersion = True
				End If
			End If
			'On each iteration of the loop check the
			'value of our _bCulture variable for a 
			'false value, meaning we havent found the culture
			'on the previous iterations
			If _hasCulture = False Then
				'Now check this index of the array for the word "Culture"
				If item.IndexOf("Culture", 0) >= 0 Then
					'Since it was found we need to pass this index of
					'the array to our GetCulture to parse the string
					'and return the culture
					_culture = >> GetCulture(item)
					'Set _bCulture to true
					_hasCulture = True
				End If
			End If
			'On each iteration of our loop we check to see
			'if our 2 values are now true, which means we have
			'the version and culture of our application
			If _hasVersion And _hasCulture Then
				'Exit the loop, no need to continue
				Exit For
			End If
		Next
	End Sub
#End Region



In this method, like the one before, you will notice 2 sets of >>'s, these are the 2 functions responsible for parsing the string sent to them to look for both the version and culture of the application of the application that caused the exception. Notice I said the application, all of this is retrieving assembly information from the application that generated the exception, not the Exception item itself.

First, we'll look at the GetVersion function, which retrieves a string delimited with equals signs (=), and based on this, if it exists, it retrieves the culture of the application where the Exception occurred:

#Region " GetVersion "
	''' <summary>
	''' Function to extract the applications version from the provided string
	''' </summary>
	''' <param name="str">String to search for the version <see cref="GetAppInfo"/></param>
	''' <returns>The applications version</returns>
	''' <remarks></remarks>
	Private Function GetVersion(ByVal str As String) As String
		'Create a string array and assign its value to the provided
		'string, split at the equals sign ("=")
		Dim version() As String = Split(str, "=")
		'Create a temp variable to hold the first index of our string array
		Dim temp As String = version(1)
		'Check to see if our temp value contains a comma
		If temp.IndexOf(",") >= 0 Then
			'Extract the version using SubString
			temp = temp.Substring(0, temp.IndexOf(","))
		End If
		'Return the version
		Return temp
	End Function
#End Region



The next function, [b]GetCulture
is also passed a equals sign delimited string (=), if it finds the delimiter then it searches the string for the Applications version, in the same manner we search for the applications version:

#Region " GetCulture "
	''' <summary>
	''' Function to retrieve the applications culture from
	''' the passed string
	''' </summary>
	''' <param name="str">String to get the culture from <see cref="GetAppInfo"/></param>
	''' <returns>The applications culture</returns>
	''' <remarks></remarks>
	Public Function GetCulture(ByVal str As String) As String
		'Create a string array and populate it the with passed
		'string slit on the equals sign
		Dim culture() As String = Split(str, "=")
		'Create a temp variable and set its
		'value to the first index of our array
		Dim temp As String = culture(1)
		'Check to see if the temp value contains a comma
		If temp.IndexOf(",") >= 0 Then
			'Since it has a comma retrieve the culture
			temp = temp.Substring(0, temp.IndexOf(","))
		End If
		'Return the value
		Return temp
	End Function
#End Region



Believe it or not, thats what i takes to do custom (structured) exception handling in VB.Net, but we're not finished yet. This last method is simply used to make sure all variabes are either emptied out, or reset to their defaults each time our exception class is initialized:

#Region " Clear "
	''' <summary>
	''' Procedure to clear the exception items when the
	''' class is initialized. This ensures we have an empty
	''' item each time we cann it
	''' </summary>
	''' <remarks></remarks>
	Private Sub Clear()
		_version = "0.0"
		_culture = "Unknown"
		_methodAction = "Unknown"
		_methodName = "Unknown"
		_user = System.Environment.UserName
		_hostMachine = System.Environment.MachineName
		_osVersion = System.Environment.OSVersion.ToString
		_hasVersion = False
		_hasCulture = False
		_exceptionLevel = "Unknown"
		_exceptionType = "Unknown"
		_stackTrace = "Unknown"
		_message = "Unknown"
		_exceptionDate = Now.ToString("yyyy/MM/dd")
		_exceptionTime = Now.ToShortTimeString
		GetAttributes()
	End Sub
#End Region



That is what it takes to do your own structured custom exception handling. I wrote this Class Library at home, but it is used is several applications, both web and Windows, at work. I do suggest one thing, if you are going to use this object for applications that have many (I mean 10,000+) concurrent users do what we did, this object was altered to simply trap the exception and passw a user friendly message back to the application, it then forwarded the exception information, via a custom MessageSchema.xsd I created (making it platform independant) to a Web Service that logged the Exceptions and send either emails or SMS's to the appropriate groups based on exception level, application and time of day.

What I did leave out of here is the logging of the Exception, this was done intentionally. All developers log differently, use different databases, and some even use network flat files, so leaving that asoect out gives you the opportunity to add your own finishing touches to a very powerful object that took weeks of research and coding to complete. Since this Class Library us under the [b]GNU General Public License
I will be distributing this class with this tutorial. With this license you can alter, modify, add or delete as you see fit, but the license file and license header must stay in tact at all times.

Thank you so much for reading, and I hope you found it useful & informative as I did while creating it. Happy Coding!
Attached File  PC_ExceptionHandler.zip (67.14K)
Number of downloads: 981

Is This A Good Question/Topic? 0
  • +

Replies To: Custom Structured Exception Handling in VB.Net

#2 T.ALAKHTIRI  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 9
  • Joined: 29-March 09

Posted 23 March 2010 - 01:47 AM

Thank you very much for this great job.

Best Regards
Tarik
Was This Post Helpful? 0
  • +
  • -

#3 Guest_Very good article*


Reputation:

Posted 22 May 2010 - 11:23 PM

The zip file is invalid.
Was This Post Helpful? 0

#4 dragonfly67  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 1
  • Joined: 22-March 14

Posted 22 March 2014 - 12:51 PM

Hi, i am quite new to VB.NET and after writing a few programms, classes and so on, I need to implement an Errorhandling into my applications. By "google-ing" about unhandled and handled exceptions in VB.NET I found your very interesting article. I read it through several times but I do not now, how I can make a sample program using your PCException Class.

It would be very nice if somebody who knows much more about vb.net than me could help me making a sample program using this class.

I am always willing to learn new stuff, but sometimes I spend so much time on something which is probably very easy. (I tried to simulate exceptions with your class for more than 1.5 days)

Thank you very much in advance. Sorry for my bad english (I am Swiss)
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1