Implement Exception Handling in ASP.NET C# Project - c#

I have an application that has many tiers.
as in, i have...
Presentation Layer (PL) - > contains all the html
My Codes Layer (CL) -> has all my code
Entity Layer (EL) -> has all the container entities
Business Logic Layer (BLL) -> has the necessary business logic
Data Logic Layer (DLL) -> any logic against data
Data Access Layer (DAL) -> one that accesses data from the database
Now i want to provide error handling in my DLL since it is responsible for executing statement like ExecureScalar and all....
And i am confused as to how to go about it...i mean do i catch the error in the DLL and throw it back to the BLL and from there throw it back to my code or what....
can any one please help me how do i implement a clean and easy error handling techinque
help you be really appreciated.
Thank you.

You can look at the MS Enterprise Block for error handling and logging. It is nice in terms of configurability. Alternatively Codelpex (codeplex.com) is the community site for MS technology open source projects. Codeplex also have some error handling libraries.

In my opinion it all depends on the kind of exception and what kind of handling you want to with it.
Some errors need to be presented to the user of course. If your application relies heavily on a database connection and your database server is unreachable you need to 'bubble' (not sure if that is the right term?) your event all the way up to your GUI and let the user know that an error occurred.
But if other errors can be handled by your application itself, you just need to 'bubble' the event up to the layer where you can handle it.
As said, there are loads of libraries which can help you handle and log errors easily and the choice for such a library is completely dependent on your project and what suits your needs.

Handle all Excpetions in DLL only, call generateEmail() for notifying admin and send only user defined error messsage from DLL-->BLL-->web-Page and redirect from here to Custom error pages
.on DLL layer generate Email along all exception info with idictionary custom defined arguments (this is what i use for my arguments)
.try catch only in DLL only
.Don't re throw exception on any layer..bad programming techniques
.send error message from DLL--BLL-->web page
.check if is the errfield !="" response.redirect("errorUserPage.")

Related

Handling exceptions from code in referenced projects

I have a C# console project where I have separated out the business logic from the UI. The business logic calls an API, retrieves JSON data, and then updates a database with the data. The UI handles the display of the results and also loops through a queue to process records with the business logic.
My question is how to properly handle exceptions thrown by the business logic. The UI project currently handles exceptions that bubble up but I want to give as detailed an error message as possible. For example, sometimes the API fails to authorize or may be down and I want to log that specific exception. The problem is the UI project does not know anything about HttpRequestException without me adding a reference to the System.Net.Http library, which creates a dependency I don't want.
What is the "best practice" for handling exceptions in a project other than where they are generated?
If you want to pass detailed messages to the UI project without explicitly referencing System.Net.Http, consider catching these HTTP exceptions in the business logic, wrapping them in an exception type you define in that library, and re-throwing the new exception. Then your UI library only needs to know about the business logic library, which it's already referencing, and the business logic can provide the most informative message possible for things it can't properly recover from.
I'd say the best practice is to not handle them. You don't know what those exceptions are, so how can you "handle" them?
Either trust the Message property of these exceptions and display them to the users, or just tell the users "sorry, something bad happened".
Keep in mind that your users will need to read the detailed messages and decide what to do about them. Quite likely they'll either ignore the messages or else call someone to ask what to do about them. Make sure you log enough information to answer the call. Sometimes, you're just better off displaying a message that says, "Please call someone who can figure out what went wrong".

How handle Business Layer error localization when there are separate UI and API front ends?

My application has both a UI (ASP.Net) and a WebServices API (WCF) front end that both invoke a single business layer. We use a custom Exception type to communicate errors from the business layer that are safe to display to end users. For example if a user attempts to perform an action that is beyond their credentials the business layer would throw a new FriendlyException("You do not have permission"). The UI layer then handles this exception and shows this message to the end user. If the API made this call then inside the FaultException data would be the "You do not have permission" message.
The problem we have now is we need to start localizing all these messages. The current thinking is to have the BusinessLayer throw static strings ("NO_PERMISSION_ERROR") that would be used by the UI and API handlers to find localized string in their respective resouce files. The only downside to this is our API localization and the UI en-US localization are essentially the same and duplicated. Can we avoid this by using some other pattern or are we on the right track?
Thanks,
J
You are definitely on the right track. You need some identifier (a static string) that need to be resolved to translated message at runtime.
Theoretically you could add something like "getLocalizedMessage(CultureInfo ci)" to your custom exception class, but this doesn't work very well with distributed applications.
Just stick to what you come up already. L10n sometimes requires some redundancy but you can't help it.

Exception handling in layered architecture

We are Refactoring (and of-course redesigning) our Services in layered design.
We have Service operations layer (BLL), Network abstraction layer -> (deals with network proxy), Data abstraction layer.
But we are a bit baffled about our exception handling strategy.
We don't want to expose too much information from BLL to outside world. (from other layers to bll is fine)
We don't want to clutter the code with try catch stacks
We don't want to mess the exception handling code(like logging, emailing etc) in catch blocks
Could someone post some code samples or literature pointers which we can use to design our simple exception handling framework?
We don't want to expose too much information from BLL to outside world.
(from other layers to bll is fine)
It's BLL itself that defines what's exposed. Make sure You show what's intended to be seen.
We don't want to clutter the code with try catch stacks
Then don't. Exceptions are exceptions. Don't control flow using them. Let them blow up.
We don't want to mess the exception handling code(like logging, emailing etc) in catch blocks
If Your logic does not rely on exception handling (which it should not) and Your code guards itself (this one is important, Your application should ALWAYS blow up on invalid state instead of working further. otherwise - it's hard to understand what causes what), then it's more than enough with wrapping whole app with only 1 error handler that dumps stack trace where necessary.
E.g. - in .net, You can use subscribing to appdomain unhandled exception event for that.
I personally use ELMAH for my web application - few lines in app.config and I have nice error log, stored in sqlite, easily accessable from web app itself. That's about all error handling I got.
Eric Lippert has a wonderful article on how to handle exceptions. I think it would be useful.
Exception handing can be as complex as you want but the good way is to use some global definition. For example by aspects which you can build with any AOP framework - part of most IoC containers like Unity, Windsor Castle, Spring.NET. Separate category of AOP frameworks is PostSharp which adds aspects on compile time insted of runtime.
Also you can check Enterprise Library 5.0 and its Exception handling application block which allows you to do policy based exception handling out of the box.

How to determine which page opened a class in another project?

I use a separate project for my data layer and call one class within it clsData.cs. I'd like to know which page from the Presentation Layer (in another project within the solution) has referenced it from the clsData side, if that's possible
Use a dedicated library like log4net, or use new StackTrace().GetFrames(), to get a reference to the current stack; that holds all the information you need, including page, method, line numbers etc.
You might want to handle the Application_Error method in your global.asax; as all uncaught exception will route to that method.
Why can't you keep the public properties inside your data access layer,which you can set from the calling class for the logging purpose?
May be you need to first understand the reason behind why you created layers in application. As far as my understanding you want to know what exactly caused a particular error. For that may be you need to think about a different solution instead of logging error in your data layer by accessing the information about the caller.
If we take a case of using the same data layer project in some other solution in different UI layer or may be a console application then would you prefer rewriting the entire data layer again to support logging who is calling your data layer class?
Whenever you make a class library (data layer) I would suggest you do the error logging related to error/exception in that scope only, and throw the error/exception as is to the caller so that the caller can get the correct idea on what happened and caller can take necessary steps.
I'm not sure what your requirement is but it is always advisable to throw the exception to the caller and log at the caller end.

Error Handling in 3 layered architecture

How do I implement error handling elegantly? For example, my data access layer can potentially throw 2 types of errors:
1) not authorized access, in which case the page should hide everything and just show the error message
2) errors that inform the user that something like this already exists in the database (say name not unique - for example), and in this case I wouldn't want to hide everything.
EDITED:
As a result of some comments here I devised that I should create derived specialized exception types, such as NotAuthorizedException, DuplicateException, etc etc.... it's all fine and dandy, however I can see 2 problems potentially:
1) Every stored proc has a return field p_error where it contains an error message. Upon getting the data from DB, I need to check this field to see what type of an error has been returned, so I can throw an appropriate exceptions. So, I still need to store my error types/error messages somewhere.....In other words, how do I should the exact message to the user (at certain times I need to) w/o checking the p_error field first. WHich brings me back to error object. Anyone?
2) I can this potentially turning into a nightmare where the number of exceptions equals the number of error message types.
Am I missing something here?
Much thanks to everyone!
You should check out the exception handling block in Enterprise Library. Lots of good tips and codeware surrounding wrapping exceptions and passing them between layers.
Where's your business layer, and why isn't it checking Authorization and integrity? The DAL is too low level to be checking those rules - if you hit a problem there, it's pretty much time to throw an exception. Your business layer or controllers can catch that exception, and display a reasonable message - but it's not something you should regularly be doing.
Create your own exception layer.
DALExceptionManager
DuplicateException
DatabaseException
BLLExceptionManager
NotAuthorizedException
InvalidDateException
In your Presentation Layer, Add this references and create a common exception handler.
In this way you know how to deal with the exception messages.
One option that I was thinking of
using is create an Error class, but
then I would need to pass it from UI
to business layer and the then to data
access layer by reference
I am not sure I understand this. You don't have to pass the error object in every layer. For example, in one of your example, errors that inform the user that something like this already exists in the database (say name not unique - for example) , a sql exception could be thrown by the framework, and you just need to catch the specific exception in your business layer, or UI layer.
Exception handling block by the Enterprise library suggested by other people will allow you define some policy-based exception handling in your web.config file. It could be good place if you want to develop some enterprise application. But for simple application, you may need not go that far.
What happens in the upper layers isn't up to your Data Access Layer. It shouldn't even be aware of what the upper layers are going to do. If you've got a duplicate key error, then it should throw something like a "DuplicateKeyException". If you should hit an authorization error (I presume you mean "exception"), then don't do anything with it - let it bubble back up to the UI layer, which can display an appropriate error page.
Remember that error status values and such things are the reason we invented exceptions.
Enterprise library exception handling block is the bomb as many have pointed out. Using policies you can do things like logging the exception, wrapping it in a different exception, throwing a new exception instead of the original one. Also, if you are looking to perform specific actions based on authentication errors or duplicate record errors etc, you could always create specific derived exception classes and catch those exception types which would precludes the need of passing any objects from the top down. Exceptions should always bubble up not down.

Categories

Resources