Best Practice Error Handling

C

csgraham74

Hi guys,

Basically i have been developing in dotnet for a couple of years but
ive had a few issues in regards to error handling.

For example - I have a class that i call passing in a stored procedure
and connection string as a path. My method returns a dataset. In my SP
i have an output parameter which tells me whether the SP select is
successful or not. If i get a error code passed back then i throw an
exception this then returns nothing back to my method call which was
expecting a dataset returned. This then throws an exception on my
webpage - the user therefore does not get the root cause of the error
and it may mislead.

My question is what is the best practice for handling such an error ???

Should i create some type of error handling method that tells the user
on the website that there is a problem and also informs myself as the
developer that there is a problem ???

any help or examples appreciated.

Thanks

CG

***CALLING CODE****** this expects a datset but gets NOTHING if there
is an error
oDS_IncomingReferrals =
obj_SiteFunctions.SQLDSReturn("OADsp_SelectUnassignedReferrals",
libRegistry.cRegistry.GetValue("gcClientAppDataConnection"))


***METHOD***

Public Shared Function SQLDSReturn(ByVal SQLStr As String,
ByVal strRegistry As String) As DataSet

Dim cnstring, str_ReturnValue As String
Dim iConn As New SqlClient.SqlConnection(strRegistry)
Dim iDataAdapter As New SqlClient.SqlDataAdapter
Dim iDataSet As New DataSet
Dim err As String
Dim cmd As New SqlCommand

Try

iConn.Open()
cmd.Connection = iConn
cmd.CommandType = CommandType.StoredProcedure
cmd.CommandText = SQLStr

cmd.Parameters.Add("@Threshhold", SqlDbType.Int)
cmd.Parameters("@Threshhold").Direction =
ParameterDirection.Input
cmd.Parameters("@Threshhold").Value = 0

cmd.Parameters.Add("@Return", SqlDbType.Int)
cmd.Parameters("@Return").Direction =
ParameterDirection.Output

iDataAdapter = New SqlClient.SqlDataAdapter
iDataAdapter = New SqlDataAdapter(cmd)
cmd.ExecuteNonQuery()

iDataAdapter.Fill(iDataSet, "tblRoleReturned")

str_ReturnValue = cmd.Parameters("@Return").Value

If str_ReturnValue <> "0" Then
ErrLabel.Text = "Error Populating dataset"
End If

SQLDSReturn = iDataSet

Catch e As Exception
err = "Unable to connect to reporting database. Please
contact Open + Direct"
End Try

End Function
 
J

jwgoerlich

I'll let you know how I do it. I cannot say whether this is a best
practice or not, for I mainly code as a hobby.

I have an object that wraps up my SQL functions in their entirety. When
executed, I use a Try-Catch to handle any local exceptions. I then copy
the exception to a local System.Exception object and set a local
Boolean value. Back in my main code, I check the Boolean to see if
anything is amiss.

Like so:

Dim bDebug as Boolean = False ' Whether or not to throw exceptions
Dim Db as New MyObj
Dim dt as New DataTable

Db.Open(ConnectionString)

If Db.Exception = True Then
' Handle the Error
If bDebug = True then Throw db.LastException
End If

dt= Db.GetTable(SomeQuery)

If Db.Exception = True Then
' Handle the Error
If bDebug = True then Throw db.LastException
End If

And so on.

J Wolfgang Goerlich
 
M

Marina Levit [MVP]

I think there are two types of errors:

1) business logic errors
2) unexpected runtime errors.

I don't think they should be handled in the same way.

For business logic errors, your function should return a message of whether
or not it was successful. Maybe that just means returning empty string to
signal failure, and whatever is calling can check the result of calling the
method. Whatever makes sense for you. Maybe it is an object with properties,
one of which is Success that says whether or not the method was successful.
There are a lot of ways to do this, and it is up to you to figure out what
works best for you. I wouldn't use globally accessible variables or
anything like that. Whatever a function returns should be sufficient in
letting the person using it know whether or not it was able to its job, in
my opinion. I wouldn't think this is something you would want to log - after
all, this is a business logic error, and it is up to the user to correct
whatever they are doing such that the business logic can validate input
successfully.

For unexpected run time errors, I would have some sort of global error
handling routine. In a web application it might be handling the Error event
for the page, in another application it might be another way. In any case,
this routine would know how to deal with unexpected errors, display an
appropriate message to the user, and if necessary log the error someplace.
The key is, all this is in one spot, so if you ever change your mind about
whether or not you want logging, or the logging mechanism, and so on - you
just change it in one place.
 
C

Cor Ligthert [MVP]

Yes,

The errorhandling for your user could result in just an Redirect of the
message that an unexpected error has happen and ask to try it later. It is
for the user not important in the even for you unexpected ones to know in
that case what.

As written by as well for you unexpected errors. The mechanisme you use, to
inform you about that can be depended from the situation where the server is
physical located. Some use a mail (SMTP) to themselves to inform them.

Our VB-Tips website by instance is located in Wiscontin, with a database
error there goes a message to Ken in Florida.

I hope this gives an idea,

Cor
 
C

csgraham74

Thanks for that guys - very informative and helpful. Il try to
implement both types of error handling from now on.

Colin Graham
 
J

Jim Wooley

For example - I have a class that i call passing in a stored procedure
and connection string as a path. My method returns a dataset. In my SP
i have an output parameter which tells me whether the SP select is
successful or not. If i get a error code passed back then i throw an
exception this then returns nothing back to my method call which was
expecting a dataset returned. This then throws an exception on my
webpage - the user therefore does not get the root cause of the error
and it may mislead.

My question is what is the best practice for handling such an error
???

***CALLING CODE****** this expects a datset but gets NOTHING if there
is an error
oDS_IncomingReferrals =
obj_SiteFunctions.SQLDSReturn("OADsp_SelectUnassignedReferrals",
libRegistry.cRegistry.GetValue("gcClientAppDataConnection"))

***METHOD***

Public Shared Function SQLDSReturn(ByVal SQLStr As String,
ByVal strRegistry As String) As DataSet

Dim cnstring, str_ReturnValue As String
Dim iConn As New SqlClient.SqlConnection(strRegistry)
Dim iDataAdapter As New SqlClient.SqlDataAdapter
Dim iDataSet As New DataSet
Dim err As String
Dim cmd As New SqlCommand
Try

iConn.Open()
cmd.Connection = iConn
cmd.CommandType = CommandType.StoredProcedure
cmd.CommandText = SQLStr
cmd.Parameters.Add("@Threshhold", SqlDbType.Int)
cmd.Parameters("@Threshhold").Direction =
ParameterDirection.Input
cmd.Parameters("@Threshhold").Value = 0
cmd.Parameters.Add("@Return", SqlDbType.Int)
cmd.Parameters("@Return").Direction =
ParameterDirection.Output
iDataAdapter = New SqlClient.SqlDataAdapter
iDataAdapter = New SqlDataAdapter(cmd)
cmd.ExecuteNonQuery()
iDataAdapter.Fill(iDataSet, "tblRoleReturned")

str_ReturnValue = cmd.Parameters("@Return").Value

If str_ReturnValue <> "0" Then
ErrLabel.Text = "Error Populating dataset"
End If
SQLDSReturn = iDataSet

Catch e As Exception
err = "Unable to connect to reporting database.
Please
contact Open + Direct"
End Try
End Function
In addition to Marina's comments, I would suggest that your DAL code not
actually catch the exception unless it can do something about it. You can
wrap the data call in a Try..Finally..End Try block with the finally being
used to close the connection. Alternativly, us a Using block in 2005 with
the connection. By not catching the exception in the DAL, it will bubble
up to the calling code with the stack trace and inner exceptions intact.
If you can do something about the exception, use an catch block. If appropriate,
re-throw the exception with a custom exception, passing the current exception
in to it's constructor so that you have the call stack and inner exception
history again.

Now in your UI, wrap the call to the DAL in a Try Catch block. On the catch,
log the exception (to a file/email/event log/etc). Present a friendly message
to the user that something happend and you are looking at it. Don't present
them with the actual exception trace. All too often, that gives hackers plenty
of information you don't want them to have. (check out some videos on SQL
injection on that one).


Jim Wooley
http://devauthority.com/blogs/jwooley/default.aspx
 

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