Catching Database Exceptions - c#

So I'm designing a Web Service and of course; I need this Service to automatically write to a Database. Which is quite straight forward; but obviously Sql has a tendency to not play nice.
Which pretty much creates a nightmare when troubleshooting, not to mention through a Web Service would make it even more of a nightmare to debug.
So I checked the internet and stumbled across an article on Stack Overflow that talked about a SqlHelper Class that essentially had a massive list of these:
public static bool IsDuplicateId(SqlException sex)
{
return (sex.Number == 2601);
}
So that implementation would be tedious, as you'd have to call all of these Methods. However, someone answered with:
switch (e.Number)
case 2601:
// Do Something
break;
default:
throw;
So I thought why not create a Class to handle a majority of these possible errors. With this particular implementation in mind:
public class SqlExceptionHelper
{
public SqlExceptionHelper(SqlException sqlException)
{
// Do Nothing.
}
public static string GetSqlDescription(SqlException sqlException)
{
switch (sqlException.Number)
{
case 21:
return "Fatal Error Occurred: Error Code 21.";
case 53:
return "Error in Establishing a Database Connection: 53.";
default
return ("Unexpected Error: " + sqlException.Message.ToString());
}
}
}
So my thought process is I have a Class that can be reused to detect some common errors; and in other classes I simply using SomeNamespace.ExceptionHelpers; I could implement something like so:
public class SiteHandler : ISiteHandler
{
public string InsertDataToDatabase(Handler siteInfo)
{
try
{
// Open Database Connection, Run Commands, Some additional Checks.
}
catch(SqlException exception)
{
SqlExceptionHelper errorCompare = new SqlExceptionHelper(exception);
return errorCompare.ToString();
}
}
}
So essentially it should handle all those lovely exceptions; but I started thinking which isn't good. Is returning such Exceptions as a return good? Can that in itself be bad? Or is this really the best way to handle such Exception catching through a Service?
So my question boils down to:
Is this the best way to handle error catching through a Service?
Thank you for the help.

Ideally web services should return relevant HTTP status codes, not exceptions. These are usually in the 200's (for OK), 400's (for errors that the user can fix themselves), or 500's (for server errors - these can be auto-retried too).
Based on your database error you get back, you can translate this to the appropriate HTTP status code. The description of the error code could be set to the exception message if you think it will help the user.

Related

Throw or not throw the exception from the methods consumed by the ASP.NET Web API layer

Assume that I am building an ASP.NET Web API application and it has the following structure:
As you can see from the diagram, the ASP.NET Web API core will talk to domain service layer (e.g. MembershipService class which has methods such as GetUsers, CreateUser, etc.) and my service classes will talk to one or multiple repositories to handle the operations.
It's very obvious that a service operation (such as MembershipService.CreateUser method) would fail for several reasons (unmet conditions, an exception thrown by the repository, etc.) and this is the place where I have the doubts.
Do you think that service classes should handle exceptions and return some sort of result object such as the below one:
public class OperationResult {
public OperationResult(bool isSuccess) : this(isSuccess) {
IsSuccess = isSuccess;
}
public OperationResult(bool isSuccess, Exception exception) : this(isSuccess) {
Exception = exception;
}
public bool IsSuccess { get; private set; }
public Exception IsSuccess { get; private set; }
}
public class OperationResult<TEntity> : OperationResult {
public OperationResult(bool isSuccess)
: base(isSuccess) { }
public OperationResult(bool isSuccess, Exception exception)
: base(isSuccess, exception) { }
public TEntity Entity { get; set; }
}
Or do you think that the service methods shouldn't abstract the exception like that and should throw the exception directly or indirectly (creating a new meaningful exception type specific to operation and put the thrown exception as its inner exception)?
When you are in-process, use exceptions.
I don't see ANY point in avoiding exceptions. Exceptions are there for good reasons, mainly to be used!
Just try to look at the big picture: you are trying to change Exception mechanism with the old fashion way of error checking. This way you'll lose all the merits of Exceptions (like separation of the error-handling and regular code, CallStack, ...) and gain nothing in return.
What I usually do in this situation is to catch the exception in service layer and rewrap it into a custom exception (with the reference to the original exception in the InnerException field).
Taking a page from Microsoft's book, the implementation of the Membership API throws exceptions rather than handling them and returning a result object, so I would consider this a best practice as long as you don't control both the client and the API.
In the case where you do control both the client and the API, it is my personal preference to return a result object or an error message. The reason for this is that I want to log capture detailed information about the source of actual exceptions, but I don't want an exception for everything that could go wrong, such as the password being incorrect.
In this case, a simple error message to the user will be more than sufficient. From real-world experience, recording exceptions to the event log or log file every time a validation error occurs is a major burden on operations personnel that are trying to determine whether or not there is an actual fault occurring or whether it is just a user's typo.

Two exception management questions

I have a couple of questions around exception management for a website:
in the catch block can I have a static class with a handle exception method that handles the exception like so:
catch (Exception ex)
{
throw ExceptionHandler.HandleException(...);
}
where ExceptionHandler.HandleException is a static method that returns a variable of type System.Exception. Is this a good practice? Any possible problems with this approach? Will it be thread safe?
In my application I have a DAL layer that is called by the Business layer and the Business layer is called by the UI. So, is it a good practice to just re-throw all Custom exceptions so they bubble up right up to the UI where they get displayed whereas System.Exception types get logged and I throw a custom exception in the catch block?
for eg in DAL and Business Layer like so:
catch (CustomExceptionBase ex)
{
throw;
}
catch (Exception sysEx)
{
ICustomExceptionBase ex = new SysException(sysEx);
ex.Handle();
throw BusinessException("Some problem while serving your request");
}
In the UI layer like so
catch (CustomExceptionBase ex)
{
//when custom exception bubbles up; code to display text to user on screen
}
catch (Exception sysEx)
{
ICustomExceptionBase ex = new SysException(sysEx);
ex.Handle();
//display error on screen;
}
Here CustomExceptionBase implements ICustomExceptionBase and inherits Exception. SysException & BusinessException both inherit from CustomExceptionBase.
Thanks for your time...
EDIT
The intent of rethrowing in the system.Exceptions block is so that if there is a fatal error like database connection lost or something similar then I log it for the technical helpdesk and return a ticket number and rethrow the same so the user knows that something went wrong and this is your reference number to follow up. For all custom exceptions in the DAL layer or Business layer, I just bubble it up all the way to the UI where the text gets displayed.
I suspect some of the answers at least are entirely down to your architecture. In the first case it all depends on what ExceptionHandler.HandleException does exactly. Does it generate a new exception based on some criteria or is it just going to return the original exception?
Whether its thread-safe or not entirely depends on its implementation. For example in the following trivial case I'd say it was thread safe:
public static Exception ExceptionHandler.HandleException(Exception ex)
{
return ex;
}
In other cases it could easily be not thread safe. eg:
public static string message;
public static Exception ExceptionHandler.HandleException(Exception ex)
{
message = ex.ToString;
sleep(2000);
return new Exception(message);
}
The latter example clearly has scope for the message variable to be changed by another thread while this one is asleep.
As for the second... Exceptions should be handled where it makes sense to handle them. There is no hard and fast rule. If some part of the code can effect a recovery from an exception (or is willing to skip over it) then catch it at that point and not earlier. If an exception is truly fatal then nothing should be trying to catch it and pretend otherwise so you should just let it bubble right up to the top and do something like alert your user that things have crashed and that you need to restart or whatever.
So really it depends on what your custom exceptions mean. If they just mean "You want to retry this" then that is different from an exception saying "Data integrity has been compromised: 0==1". both of these may be custom so really its for you to decide where to handle things.
Yes, you can call a static exception handler inside a catch block and it will likely be threadsafe as long as you don't reference any static variables.
You should look at Microsoft's Enterprise Library. It has nearly this same design but uses exception policies defined in the web.config to control how the exception is bubbled, wrapped or discarded. Couple that with the Application Logging block and you have a complete solution.
In itself there aren't any technical problems having a static method to handle exceptions / rethrow exceptions, however from a best practices point of view having a single method that magically "handles" exceptions strikes me as a potential code smell. Exceptions are by their very name exceptional, each individual case requires thought to go into it to make sure that you are doing the correct thing and so I find it unlikely that your HandleException method will always be doing something sensible.
As an extreme example I know of one such application where pretty much every single method was wrapped in a try-catch block with a call to an static exception handler method which threw a generic MyApplicationException type. This is an extremely bad idea:
It clutters the code
It makes it harder to make sense of stack traces
It makes it very difficult for callers to catch and handle specific exceptions types
It makes throwing an exception an even bigger performance penalty than before
My favourite was a method which wasn't implemented which looked a bit like this:
void SomeException()
{
try
{
throw new NotImplementedException();
}
catch(Exception ex)
{
throw ExceptionHandler.HandleException(...);
}
}
The worst bit of this of course that it is completely mindless. As I said before exceptions are exceptional - each try ... catch block requires careful thought and consideration to be put into how it should behave, the use of a generic HandleException method is an immediate warning flag that this probably isn't the case.
Rethrowing exceptions
Generally speaking you should only rethrow an exception in two cases:
When you want to add contextual information to an exception (such as the name of the current file being processed)
When you had to catch an exception in order to handle some specific case, e.g. handling an "out of disk space" error
catch (IOException ex)
{
long win32ErrorCode = Marshal.GetHRForException(ex) & 0xFFFF;
if (win32ErrorCode == ERROR_HANDLE_DISK_FULL || win32ErrorCode == ERROR_DISK_FULL)
{
// Specific "out of disk space" error handling code
}
else
{
throw;
}
}
"Bubbling" (i.e. catching and rethrowing an exception without doing anything with it) is completely unneccessary - this is what exceptions are already designed to do all by themselves!
Handling exceptions
Other people have said "exceptions should be handled where it makes sense" and I have even given this advice myself, but in hindsight I don't think thats particularly useful advice! :)
What people generally mean by that is that you should handle exceptions for specific reasons, and that you should choose where in your application to handle that exception depending on that reason.
For example if you want to display an error message to inform the user that they don't have permission to modify a file if you get an access denied error then you may have a specific try-catch block in your UI code that does this:
catch (IOException ex)
{
long win32ErrorCode = Marshal.GetHRForException(ex) & 0xFFFF;
if (win32ErrorCode == ERROR_ACCESS_DENIED)
{
// Display "access denied error"
}
else
{
throw;
}
}
Note that this is very specific to this one case that we wish to handle - it catches only the specific exception type were are interested in and performs additional checks to filter down to the specific case we are interested in.
Alternatively if you want to log unhandled errors or gracefully display error messages to the user instead of an IIS 505 error screen then the place to do this is either in Global.asax or through a custom error page - ASP.Net Custom Error Pages
My point is that when handling exceptions we are are thinking carefully about what it is we want to achieve in terms of application functionality (e.g. retry logic, error messages, logging etc...) and implementing our exception handling logic to specifically address those requirements in the most targeted way possible - there is no magic exception handing framework and there is no boilerplate code.
Avoid exceptions entirely whenever possible!
I usually find that the best strategy is simply to avoid exceptions entirely whever possible! For example if your page parses user enter numbers and you want to display validation messages when they enter stupid values then validate your input up-front instead of catching exceptions:
Bad:
void DoSomething()
{
int age = int.Parse(ageTextBox.Text);
if (age < 0)
{
throw new ArgumentOutOfRangeException("age must be positive");
}
if (age >= 1000)
{
throw new ArgumentOutOfRangeException("age must be less than 1000");
}
}
void Button_Click(object sender, EventArgs e)
{
try
{
DoSomething();
}
catch (Exception ex)
{
DisplayError(ex.Message);
}
}
Good:
void Button_Click(object sender, EventArgs e)
{
int age;
if (!int.TryParse(ageTextBox.Text, out age))
{
DisplayError("Invalid age entered");
}
if (age < 0)
{
DisplayError("age must be positive");
}
if (age >= 1000)
{
DisplayError("age must be less than 1000");
}
DoSomething();
}
Users enter invalid data all of the time - handling this is really application logic and shouldn't fall into the real of exception handling - its certainly not an event that I would call "exceptional".
Of course this isn't always possible, however I find that using this strategy simplifies the code and makes it easier to follow application logic.
First of all we need to consider Exception types, In any business exception can be either BusinessException or Technical/SystemException.
In BusinessException we can send custom exceptions with error
details.
In Technical/System Exception we should not handle it, but let it
popup to UI layer.UI Can decide what error should be displayed in
case of exceptions.
In your approaches, if you handle exception or throw the custom
exception the call trace is lost.

How to refactor logging in C#?

In my services all exposed methods have:
try
{
// the method core is written here
}
catch(Exception ex)
{
Log.Append(ex);
}
It's boring and ugly to repeat it over and over again. Is there any way to avoid that? Is there a better way to keep the service working even if exceptions occur and keep sending the exception details to the Log class?
Try AOP. This is the most widely-used selling point of AOP.
Also, see this discussion here on SO.
You could set up a generic error handling method for all uncaught exceptions like so:
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(UnhandledException);
Depending on what went wrong, you may not be able to recover from the error... but this should hopefully give you some idea of what what went wrong. If it gets to the point where your application code hasn't handled the exception gracefully, this method could attempt to reinitialize the service to a known working state.
I came up with a semi-solution right now. I can refactor the code:
public TResult ExecuteAndLogOnError(Func<TResult> func)
{
try
{
return func();
}
catch(Exception ex)
{
// logging ...
}
}
And then you can call it on each method:
return ExecuteAndLogOnError(() =>
{
// method core goes here..
});
Which is 4 lines shorter than the original scenario.
In such cases I always use centralized error handlers.
In WCF it is very easy. Some more details:
http://www.haveyougotwoods.com/archive/2009/06/24/creating-a-global-error-handler-in-wcf.aspx
Basically, you just implement the IServiceBehavior interface and then provide your own error handler. That is the best way to do this because you don't have to write any code that handles fatal exceptions (I mean exceptions that you can only log and you don't know what to do about them) in your methods.
If all your doing is logging then just log the error at a later stage... No need to log the error early. If you do more than log the error, well then you're gonna need the try..catch anyway. And if you swallow exceptions (IE. just log them and then go on as if nothings happened) then maybe you're doing it wrong...
I once used something like the Template Function Pattern to resolve a problem like this. I had a base class that did something like:
public void Execute()
{
try
{
ExecuteImplementation();
}
catch (Exception ex)
{
// Log ex
}
}
public abstract void ExecuteImplementation();
There was one derived class per web service operation. The derived classes each implemented ExecuteImplementation.
The web service operations did:
[WebMethod]
public Result WebOperation(Request request)
{
WebOperationClass instance = new WebOperationClass(request);
instance.Execute();
return instance.Result;
}
Exception filters would be good for this. Alas, .NET supports them through MSIL, C++/CLI, VB.NET, but not C#.
If all you're doing in your catch is logging the exception, you could maybe just use a custom error page and let ELMAH log all your uncaught exceptions.
A previous poster brought up AOP (Aspecte-Oriented Programming).
I use PostSharp for basic logging traces/exceptions.
It's quite easy to use and setup.
Check out this link and watch the tutorial.
http://www.sharpcrafters.com/postsharp
--crap it is no longer open source ... anyways you can grab Postsharp1.5 and mess around with it to see if it is something you are interested in it.
I am also in no way affiliated with PostSharp. I'm just a user.

Proper catching of specific exceptions through web service

I am currently using a C# .NET Service in our client program. As part of the server design, several custom made exceptions are thrown to indicate specific errors (as in any normal desktop program).
The problem is that the Web Service catches these errors and serializes them into a FaultException, with the actual exception (like NoRoomsAvailableException) written in the Message field.
My question is whether there is a best practice for handling these errors. We have just begun working on this, and we would probably do some text pattern matching to pull out the exception type and error message, but it seems like a hacky way to do it, so any "clean" way of doing it would be much appreciated.
The proper way would be to define fault contracts. For example in your web service you could do the following:
[DataContract]
public class NoRoomsAvailableFaultContract
{
[DataMember]
public string Message { get; set; }
}
Next you declare this contract for a given service operation
[ServiceContract]
public interface IMyServiceContract
{
[OperationContract]
[FaultContract(typeof(NoRoomsAvailableFaultContract))]
void MyOperation();
}
And you implement it like so:
public class MyService : IMyServiceContract
{
public void MyOperation()
{
if (somethingWentWrong)
{
var faultContract = new NoRoomsAvailableFaultContract()
{
Message = "ERROR MESSAGE"
};
throw new FaultException<NoRoomsAvailableFaultContract>(faultContract);
}
}
}
In this case the NoRoomsAvailableFaultContract will be exposed in the WSDL and svcutil.exe could generate a proxy class. Then you could catch this exception:
try
{
myServiceProxy.MyOperation();
}
catch (FaultException<NoRoomsAvailableFaultContract> ex)
{
Console.WriteLine(ex.Message);
}
darin has the correct answer. I'll only say explicitly what he implies: web services do not pass exceptions. They return SOAP Faults. If you define your faults properly, as he does, then you get to throw FaultException<fault>. This will become a SOAP Fault with fault in the detail element. In the case of a .NET client, this will then be turned into a FaultException<fault>, which you can catch.
Other platforms may handle this somewhat differently. I've seen IBM's Rational Web Developer generate Java proxy code that creates a separate exception for each declared fault. That was a version before Java generics, so maybe by now it does the same thing as .NET does.

Easy way to catch all unhandled exceptions in C#.NET

I have a website built in C#.NET that tends to produce a fairly steady stream of SQL timeouts from various user controls and I want to easily pop some code in to catch all unhandled exceptions and send them to something that can log them and display a friendly message to the user.
How do I, through minimal effort, catch all unhandled exceptions?
this question seems to say it's impossible, but that doesn't make sense to me (and it's about .NET 1.1 in windows apps):
All unhandled exceptions finally passed through Application_Error in global.asax. So, to give general exception message or do logging operations, see Application_Error.
If you need to catch exeptions in all threads the best aproach is to implement UnhandledExceptionModule and add it to you application look here
for an example
Use the Application_Error method in your Global.asax file. Inside your Application_Error method implementation call Server.GetLastError(), log the details of the exception returned by Server.GetLastError() however you wish.
e.g.
void Application_Error(object sender, EventArgs e)
{
// Code that runs when an unhandled error occurs
log4net.ILog log = log4net.LogManager.GetLogger(typeof(object));
using (log4net.NDC.Push(this.User.Identity.Name))
{
log.Fatal("Unhandled Exception", Server.GetLastError());
}
}
Don't pay too much attention to the log4net stuff, Server.GetLastError() is the most useful bit, log the details however you prefer.
The ELMAH project sounds worth a try, its list of features include:
ELMAH (Error Logging Modules and
Handlers) is an application-wide error
logging facility that is completely
pluggable. It can be dynamically added
to a running ASP.NET web application,
or even all ASP.NET web applications
on a machine, without any need for
re-compilation or re-deployment.
Logging of nearly all unhandled exceptions.
A web page to remotely view the entire log of recoded exceptions.
A web page to remotely view the full details of any one logged
exception.
In many cases, you can review the original yellow screen of death that
ASP.NET generated for a given
exception, even with customErrors mode
turned off.
An e-mail notification of each error at the time it occurs.
An RSS feed of the last 15 errors from the log.
A number of backing storage implementations for the log
More on using ELMAH from dotnetslackers
You can subscribe to the AppDomain.CurrentDomain.UnhandledException event.
It's probably important to note that you are not supposed to catch unhandled exceptions. If you are having SQL timeout issues, you should specifically catch those.
Do you mean handling it in all threads, including ones created by third-party code? Within "known" threads just catch Exception at the top of the stack.
I'd recommend looking at log4net and seeing if that's suitable for the logging part of the question.
If using .net 2.0 framework, I use the built in Health Monitoring services. There's a nice article describing this method here: https://web.archive.org/web/20210305134220/https://aspnet.4guysfromrolla.com/articles/031407-1.aspx
If you're stuck with the 1.0 framework, I would use ELMAH:
http://msdn.microsoft.com/en-us/library/aa479332.aspx
hope this helps
There are 2 parts to this problem handling & identifying.
Identifying
This is what you do when the exception is finally caught, not necessarily where it is thrown. So the exception at that stage must have enough context information for you to idenitfy what the problem was
Handling
For handling, you can
a) add a HttpModeule. See
http://www.eggheadcafe.com/articles/20060305.asp
I would suggest this approach only when there is absolutely no context informaatn available and there might be issuus wiih IIS/aspnet, In short for catastrophic situations
b) Create a abstract class called AbstractBasePage which derives from Page class and have all your codebehind classes derive from AbstractBasePage
The AbstractBasePage can implement that Page.Error delegate so that all exceptions which percolate up through the n-tier architecture can be caught here(and possibly logged)
I would suggest this cause for the kind of exceptions you are talking about (SQlException) there is enough context information for you to identify that it was a timeout and take possible action. This action might include redirecting user to a custom error page with appropriate message for each different kind of exception (Sql, webservice, async call timeouts etc).
Thanks
RVZ
One short answer is to use (Anonymous) delegate methods with common handling code when the delegate is invoked.
Background: If you have targeted the weak points, or have some boilerplate error handling code you need to universally apply to a particular class of problem, and you don't want to write the same try..catch for every invocation location, (such as updating a specific control on every page, etc).
Case study: A pain point is web forms and saving data to the database. We have a control that displays the saved status to the user, and we wanted to have common error handling code as well as common display without copy-pasting-reuse in every page. Also, each page did it's own thing in it's own way, so the only really common part of the code was the error handling and display.
Now, before being slammed, this is no replacement for a data-access layer and data access code. That's all still assumed to exist, good n-tier separation, etc. This code is UI-layer specific to allow us to write clean UI code and not repeat ourselves. We're big believers in not quashing exceptions, but certain exceptions shouldn't necessitate the user getting a generic error page and losing their work. There will be sql timeouts, servers go down, deadlocks, etc.
A Solution: The way we did it was to pass an anonymous delegate to a method on a custom control and essentially inject the try block using anonymous delegates.
// normal form code.
private void Save()
{
// you can do stuff before and after. normal scoping rules apply
saveControl.InvokeSave(
delegate
{
// everywhere the save control is used, this code is different
// but the class of errors and the stage we are catching them at
// is the same
DataContext.SomeStoredProcedure();
DataContext.SomeOtherStoredProcedure();
DataContext.SubmitChanges();
});
}
The SaveControl itself has the method like:
public delegate void SaveControlDelegate();
public void InvokeSave(SaveControlDelegate saveControlDelegate)
{
// I've changed the code from our code.
// You'll have to make up your own logic.
// this just gives an idea of common handling.
retryButton.Visible = false;
try
{
saveControlDelegate.Invoke();
}
catch (SqlTimeoutException ex)
{
// perform other logic here.
statusLabel.Text = "The server took too long to respond.";
retryButton.Visible = true;
LogSqlTimeoutOnSave(ex);
}
// catch other exceptions as necessary. i.e.
// detect deadlocks
catch (Exception ex)
{
statusLabel.Text = "An unknown Error occurred";
LogGenericExceptionOnSave(ex);
}
SetSavedStatus();
}
There are other ways to achieve this (e.g. common base class, intefaces), but in our case this had the best fit.
This isn't a replacement to a great tool such as Elmah for logging all unhandled exceptions. This is a targeted approach to handling certain exceptions in a standard manner.
Timeout errors typically occur if you are not forcefully closing your sqlconnections.
so if you had a
try {
conn.Open();
cmd.ExecuteReader();
conn.Close();
} catch (SqlException ex) {
//do whatever
}
If anything goes wrong with that ExecuteReader your connection will not be closed. Always add a finally block.
try {
conn.Open();
cmd.ExecuteReader();
conn.Close();
} catch (SqlException ex) {
//do whatever
} finally {
if(conn.State != ConnectionState.Closed)
conn.Close();
}
This is old question, but the best method (for me) is not listed here. So here we are:
ExceptionFilterAttribute is nice and easy solution for me. Source: http://weblogs.asp.net/fredriknormen/asp-net-web-api-exception-handling.
public class ExceptionHandlingAttribute : ExceptionFilterAttribute
{
public override void OnException(HttpActionExecutedContext context)
{
var exception = context.Exception;
if(exception is SqlTimeoutException)
{
//do some handling for this type of exception
}
}
}
And attach it to f.e. HomeController:
[ExceptionHandling]
public class HomeController: Controller
{
}

Categories

Resources