Mazen Elkashef
Mazen Elkashef

Reputation: 3499

What's the best way to handle the exceptions and how to deal with them in asp.net

First, I'm already familiar with the simple exception handling syntax but I'm asking about the best place, the best time and the best way to deal with them.

I'm building an N-Layered application. so I think the DAL will sometime generate some errors to handle .. and I just learned about the SqlException class, what's the deal with that class ? I once saw a code that handles the SqlException then it handles Exception!

After knowing the practice and where I'm going to handle them, I'm planning to create a method to connect to the database and log the errors in a database so I could fix it but still I don't know what information should I collect to allow me identify the whole situation!


I thought exceptions handling was not a big deal. but every now and then I read some strange advices -that I never understood- on the questions comments but no one could answer me since it was some very old questions!

"Don't just explicitly catch exceptions"

"the code that is used by higher-layers in your application must always only throw exceptions and never worry about how to deal with them."

EDIT

What about Page_Error event and Application_Error .. I saw that they are a good practice for handling errors

Upvotes: 3

Views: 3961

Answers (5)

Rob
Rob

Reputation: 10248

IMO apart from extremely rare circumstances I only ever use exception handling for I/O related code where there are interactions with services and file systems whose functionality and maintenance is beyond the control of my applications.

I have always considered the use try/catch statements to manipulate the logic (flow-of-control) in a program in the same way if/else statement work to be extremely bad practice. Most common exceptions can be avoided if you use the tools at hand correctly.

Upvotes: 0

usr-local-ΕΨΗΕΛΩΝ
usr-local-ΕΨΗΕΛΩΝ

Reputation: 26874

Exception handling is a big deal, and it's not simple to design a good strategy for that.

First of all, some general rules:

  • Exceptions occur when the running code is completely unable to go ahead, so maybe it tried to handle some internal exceptions but ultimately failed. Think about TCP connection: if a damaged packet arrives, it's an exception, but TCP protocol can handle it. If too many are damaged, an I/O or socket exception is thrown
  • Exceptions can not always be handled. In almost all cases, when you get an exception from underlying layers you are unable to run corrective code. If your application depends on a DB and that is offline, when you get the exception about it you can only display an error message
  • Exceptions can be unexpected, and can reveal design or implementation flaws. For example, an implementation flaw can be the situation in which you have a redundant DB but when you fail to connect to frist mirror you don't try with the second

For the third point, it's important to log exceptions and periodically analyse logs to find any weird situation. So, let's begin with the concrete answer.

First of all

think about "handling" the exception. When you write every single code line, think about the possible problems that may prevent it from completing, and think about the possible corrective actions. if any are possible. An error message is not a good handling way, it's the latest strategy.

Don't start to write try-catch(Exception), but prefer specific exceptions. If you need to parse strings to numbers etc, then expect FormatException, if you need to cast from Object to your type expect InvalidCastException

When you write lower-level layers

don't hesitate to throw exceptions!! Don't do like many folks do, ie. return null or use (like ANSI C) a boolean return value and reference parameters. Exceptions are there for that. If you can handle an exception (ie. you don't find a local file but you know you have a remote backup, so handle FileNotFoundException by calling the remote mirror, but if you can't still connect then ultimately throw) then do it and try to resume computation, but if you cannot then throw. And don't forget to throw the inner exception, if present, because it is helpful for logging in the highest layer.

Basically, you can still decide to throw an exception on your own even if you don't catch any! And this is highly recommended especially when function parameters are invalid!

Another good option is to still log in the underlying layers. You actually want to log no matter an exception occurs.

When you log

remember to give an adequate severity to the messages. If you find via code that your DB is offline, that's not an unexpected exception. Still log it as an error, but don't worry about code bugs when you investigate the logs. Instead, if you catch an exception that your code is unable to recognize (a NullReferenceException is a classic example) then log with highest severity, ie. fatal, to give it maximum priority!

A good strategy for ASP.NET

can surely be based upon Page.OnError method. If you have a base page class for all of the pages of your site, you should definitely override that method. In that method, you should first log your exception.

You also shouldn't abuse of try-catch(Exception) blocks, because if you don't catch an exception you can't handle with catch, you will have to handle it via OnError.

When you run such a method, don't immediately think about Server.RemoveError(). You can prefer to have a static HTML page for HTTP 500 error (that is triggered when an unhandled exception bubbles to ASP.NET runtime) that displays a courtesy message to the user.

Briefly

  1. Don't hesitate to throw in underlying layers if anything strange occurs
  2. As said by your advice, don't handle exceptions you are unable to handle (if you catch an exception you can't handle, rethrow it)
  3. LOG!!!!!!!!!!!!!!!!!
  4. Don't disclose exception details to final users on a public website, never!! By default, ASP.NET prevents that from occurring, but you could still use OnError to print stack trace
  5. Use OnError, or Application_Error as single central point to handle all unexpected exceptions
  6. Periodically examine logs against error/fatal messages to find issues with your code, then think about maintaining/debugging/fixing it

Upvotes: 8

sajoshi
sajoshi

Reputation: 2763

I think what you are asking here is a Error/Exception Handling Strategy for any application.

I think it includes:

Where - All places where you think an exception can occur or which need more monitoring like DB calls, External Service Calls, Use of Arrays, User Input Parsing, Type Casting and so on...

How - All you high level layers should throw the exception and it should be captured at the entry point and processed to understand the root cause. Usually you do this in Application_Error() where you catch the exception and log it for troubleshooting. How you log an exception is upto you. A Log File or DB driven log is an option based on your requirements and available resources.

Upvotes: 1

Paul Rowland
Paul Rowland

Reputation: 8352

The how/when/where to catch exceptions may depend on what your trying to do exactly, its difficult to give an exact catch all always correct answer.


As to your specific questions,

I just learned about the SqlException class, what's the deal with that class ? I once saw a code that handles the SqlException then it handles Exception!

Its good practice to handle the specific exception you believe may occur, if your not sure what type this exception is you can just 'Exception', if you want something specific to occur on a 'SQLException' and something else to happen with an 'Exception' then there is certainly nothing wrong with writing code that handles both.


"Don't just explicitly catch exceptions"

I believe this is refering to code like this

try 
{
   int i = 1/0;
} 
catch(Exception e)
{
  //do nothing
}

This exception will be caught but you'll never know it happened, hence this is not a good idea, and the person using the code will be scratching their head as to whats going on.

Upvotes: 1

Chris Kooken
Chris Kooken

Reputation: 33870

Take a look at elmah. It's a logger for asp.net. Renders all errors on a nice summary page.

http://code.google.com/p/elmah/

The best way to handle exceptions is in the specific layer they apply to. If it is a constraint volation, for example, 2 users with the same name, you should let that bubble up to the UI and alert the user.

Same goes with any business rule violations. Those should bubble up to the UI so the end user knows what went wrong.

A SQL Connectivity error is best handled in the DAL...etc..

Upvotes: 1

Related Questions