views:

101

answers:

2

Looking for suggestions/best practices on managing error codes and messages in a multi-tiered applications. Specifically things like:

  1. Where should error codes be defined? Enum? Class?
  2. How are error messages or further details associated with the error codes? resource files? attributes on enum values, etc.?
  3. If you have a multi-tier application consisting of DAL, BLL, UI, and Common projects for example, should there be a single giant list of codes for all tiers, or are the codes extensible by project/tier?

Update: Important to mention that I can't rely solely on Exceptions and custom Exception types for error reporting, as some clients for this application will be via web services (SOAP & REST)

Any suggestions welcome!

+2  A: 

I think It is better to create a Common Project ( or ApplicationFramework Project ) and put your Exceptions and Common Object on it.

It is always a good idea to have a ApplicationFramework which contains Base Class for your Classes ( specially in UI - PageBase - MasterBase- ModuleBase and etc)

And as its obvious you have to put your classes and Enums in your BLL project.

Note that 3 tier doesn't mean 3 Project. You can have 5 project in your BLL.

Finally don't forget to use ELMAH or any other similar tools.

Nasser Hadjloo
+3  A: 

Error codes are old skool, you needed them back in the bad old days of COM and C programming, environments that didn't support exceptions. Nowadays, you use exceptions to notify client code or the user about problems. Exceptions in .NET are self-descriptive, they have a type, a message and diagnostics.

You need to distinguish two types of exceptions, those that are reasonably recoverable and those where you have no idea what exactly went wrong or how you recover from them. The latter kind is by far the most common, you'll need a human to take corrective action. Use one of the standard built-in .NET exception types to raise them. IllegalOperationException, FormatException, ArgumentException are common choices. If it is the back-end that raises such an exception then you just want to pass it through without altering. You typically need a finally block to ensure your internal state is consistent, sometimes a catch block that contains a simple throw to recover state.

Anything you consider recoverable should be raised with an exception type that you declare yourself, derived from the Exception class. That gives code upstream a chance to write a catch clause and do something meaningful. You'll need to generate a Message that is descriptive of the problem, in case the up-stream code doesn't actually handle it, the text of the message needs to be retrieved from either a hard-coded string or a resource if you support localization.

Hans Passant
Thanks for the input. I've updated the original question to mention that I can't rely solely on exceptions as some clients will be via web services, and specifically REST web services which don't have the concept of "exception types". Looking at some of the internet API's (Facebook, Flickr, etc.) leads me to believe that error codes in this usage are the way to go.
WayneC
@WayneC: SOAP web services have access to SOAP Faults. Too bad that REST is requiring you to revert to the early '90s.
John Saunders
@John: Are you saying that REST API's are the "early 90's"? Somebody better tell Facebook, Flickr, Netflix, Twitter, Google, etc. that they should get with the times! :-) Even with the exception approach, error codes can still be valuable to further categorize an exception. For example if you have a custom ValidationException you could have error codes to detail the type of validation that failed as opposed to creating a new custom exception type for every validation scenario.
WayneC
@WayneC: I'm saying REST APIs have returned us back to error codes, which I thought we'd done away with when we grew up and learned to use exceptions. I wonder if you have a real scenario where you need to look into your ValidationException programmatically to see the error code. Why do you need to know that level of detail? For reporting? Put it in the Message property.
John Saunders
I'm pretty sure he is, REST dated from the days of "less is better". Heavily influenced by the Unix approach to error messages. Like "User unknown: not a bicycle" and "Too many recipients for no message body". The end result of well meaning programmers trying to interpret an error code. Google the error message to find the fun PDF.
Hans Passant
WayneC
@WayneC: I think that REST should grow up and learn to support exceptions. I don't care how. In my opinion, the best way to handle error codes is to not use them. If you're stuck using them, good luck managing what the rest of us have learned to discard.
John Saunders
@John: I guess we'll agree to disagree...but when you say "good luck managing what the REST of us have learned to discard" (no pun intended right? :-) )....it looks like the "rest of you" are in the minority. Take a look at the largest, most widely used web service API's out there and how they handle error reporting:Ebay - SOAP/Faults + Error Codes; Facebook - REST/Error Codes; Twitter - REST/Error Codes; Flickr - SOAP Amazon - SOAP Google - SOAP
WayneC
@WayneC: I did not use "REST" in a pun. I said "what the rest of us have learned to discard". BTW, talk to me in another 10 years and we'll be able to decide whether or not REST was a fad. I think it will wind up having been an idea driven by circumstance, and the circumstances will have changed.
John Saunders
@John: Again you miss the point...and my sarcasm regarding the "pun". I don't really care if the service is SOAP or REST or RPC or some proprietary format nobody's ever heard of. My point was many, many large audience API's which have REST and/or SOAP endpoints ALSO use error codes. So, the use cases must be there in "real world" situations. But yet, you arrogantly dismiss them and instead recommend that everyone switch to SOAP?! Thanks for the "help" and please don't respond to any of my posts in the future.
WayneC
http://msdn.microsoft.com/en-us/library/aa489593.aspx http://msdn.microsoft.com/en-us/library/aa385638(VS.85).aspx
John Saunders
@John: Both articles are almost completely irrelevant to the question asked. Thanks for playing.
WayneC
@WayneC: Both articles are directly related to maintaining error codes and messages, and are associated with the most recent Microsoft technologies that need error codes. And, what game could I be "playing" in comments? There's no rep involved.
John Saunders
@John: What? If you really think an article about defining error codes in a low-level Windows driver, and an Event Log message compiler reference "directly relate" to the question I asked...then it's obvious you've missed the point completely. Please stop while you're ahead. You've not contributed anything useful to this post.
WayneC
Can you guys find another post to bitch at each other please?
Hans Passant
@nobugz: would you or someone else please tell this guy the cycle that was used on maintaining and using error codes in "low-level device drivers". I'm trying to point out to him how we used to do this in the "old skool", but I think someone else needs to be the one to explain it to him.
John Saunders
@John: You still don't get it. Please QUIT RESPONDING. I can understand now why 1 out of every 4 of your voted comments is down.@nobugz: Thanks for your original reply and the "quit bitching" comment..(you're right..I upvoted it! :-) ) I'm just sorry that Mr. Saunders had to hijack it with irrelevant links and condescending remarks.
WayneC
A comment on the original answer - custom exceptions should inherit from ApplicationException, not Exception.http://msdn.microsoft.com/en-us/library/system.applicationexception%28VS.71%29.aspx
BenV
@Ben: outdated, "you are advised to derive custom exceptions from the Exception class". Link: http://msdn.microsoft.com/en-us/library/system.applicationexception.aspx
Hans Passant
@Hans: Right you are, I haven't seen that before. Thanks for the correction.
BenV