RE: Exception Handling Opinion 2004-12-14 - By Tom Mallard
In this case, if an unhandled exception is thrown by checking inventory to me something's wrong with the logic regardless of layer as this should only happen during development and never in production. Anything that can go wrong must be covered or the logic is just not up to what most would call robust.
In the case of an error coming from the data layer, the BLL would normally return a standard error page to the UI with a link for continuing or returning to the previous step in a workflow process. This would be a normal page specifically to deal with the UI in a way that's insulated from the actual error.
Of course the dev team should be notified of the error and for them any actual error messages would be forwarded to them using some type of logging, alert or messaging depending on the type and severity of the error. So from my view, an error would never be allowed to bubble to the UI, the UI would only receive a normal page designed to keep the user's workflow going, or, to inform them of what to do since the app can't continue.
Good discussion ...
Just an opinion to add on the heap,
tom mallard software design/analysis/arch mallard-design.com kitesport.com - biki-bike.com
----- Original Message ----- From: "J. Ambrose Little" <ambrogio@(protected)> To: <aspnet-architecture@(protected)> Sent: Monday, December 13, 2004 5:36 PM Subject: [aspnet-architecture] RE: Exception Handling Opinion
> I disagree that you should handle exceptions on every layer. If you > can't handle an exception meaningfully, you should let it bubble. > Whether this is by not handling or by wrapping it in another exception > using, e.g., the InnerException property, depends on whether or not > you can add any value. If you can't add value, let it bubble. > > Saying that validating inventory should be a business layer function > is not, IMO, to the point. If the data store is keeping track of > inventory, you have to go to the data store to validate inventory. So > at some point, the data tier is involved in the business rule. > Clearly, if he's throwing an exception when inventory is unavailalbe, > this is happening in code and the distinction between the data tier > and the business tier at that level is at best blurry. > > I'd only suggest that maybe checking inventory in a separate operation > to avoid exceptions might be a better approach, depending on the > architectural topology, i.e., whether or not it is prohibitively > expensive to do so. > > --Ambrose > > On Mon, 13 Dec 2004 17:17:57 -0600, Robert Hanson <rhanson@(protected)> wrote: > > > > > > I'd argue that ensuring that they "have enough inventory on hand" is a > > business layer function, not a DB level function. Sure, you ought to > > have > > constraints in the DB that won't let you create a negative inventory, > > but > > you should never let your application try to store a record that would > > cause a business rule violation > > > > (I won't get into the case where physical inventory and "book" inventory > > get out of whack - like the time when I went to look up a price for an > > item, and the computer said we had none on hand, even though I actually > > had > > one in my hand at the time.... If that one was sold, then the inventory > > would have gone negative) > > > > You certainly can pass information from a lower layer to the next higher > > layer; but at that next higher layer, there should be code that traps > > those exceptions and deals with them. One way of dealing with them is > > to > > send a new message upwards again; but you should not be passing a > > message > > from the DB straight up the chain to the UI. Let each layer handle the > > message and decide what to do with it. > > > > One cleaner method is to pass a "messages" object down one layer (that > > is, > > when you make a call from your business layer to your DAL layer) pass > > along > > a "messages" object to that layer. I'd make the "messages" object > > impliment a simple interface, where perhaps you can only "addMessage" or > > "addException". This make the interface pretty clean and lightweight. > > When the call returns from the lower layer, the current layer can > > examine > > the messages object and take appropriate action. > > > > I appreciate your thoughts about "return values" and HResult. But by > > using > > an intelligent object instead of a return value, you can capture a lot > > more > > information about the exception, and pass that info back up into the > > previous layer. This gives you a lot more possibilities than a single > > return value, or a single exception. For example, the messages object > > could impliment some logic that determines the severity of the > > exception, > > and whether to abort the current method being executed, or just to log > > the > > exception and continue. (And since it is the previous layer that > > instanciates the messages object and passes it down, the previous layer > > has > > control over the logic that is contained within the messages object.) > > > > Just hoping to trigger a few thoughts about alternatives. > > > > Tim Weaver <icodemarine@(protected)> on 12/13/2004 03:37:50 PM > > > > Please respond to aspnet-architecture@(protected) > > > > To: aspnet-architecture@(protected) > > cc: > > > > > > > > Subject: [aspnet-architecture] RE: Exception Handling Opinion > > > > J. makes a great point about using exceptions to handle > > non-exceptional data. The problem we faced was that at the DB layer > > validations was done against the customs account to ensure they had > > enough inventory available. If they didn't then some sort of message > > had to go back to the UI to tell the user. > > > > You can certainly argue that this isn't exceptional (in fact I did > > when approached about this). However, you still have the problem of > > how to get the information back to the caller. You could force the > > caller to wait for a return value and then build a message based upon > > what was sent down the stack, but that is a lot of work spread out all > > over the UI. > > > > If you use return values all the way up the stack then you are > > basically building HResults because any given call is going to have > > different data to return. We needed to have contextually aware > > information returned and exceptions allowed us to do it in a concise > > way. I'm still on the fence about the whole approach, but its hard to > > argue that using exceptions didn't produce much cleaner/simpler code. > > > > We attempt to tackle all our problems with an agile approach. One of > > the tenants that we adhere to (or try) is to keep things as simple as > > possible. Sometimes simple is better than elegant even if it costs you > > a few cycles... > > > > Tim > > > > On Mon, 13 Dec 2004 15:42:43 -0500, J. Ambrose Little > > <ambrogio@(protected)> wrote: > > > Eh? It can't fall (bubble) anywhere farther (higher) than the > > > application level of the UI tier. And I use a plain HTML error page, > > > so no errors can occur on it. > > > > > > In any case, IMO, using exceptions is okay as long as you only throw > > > them when you cannot meaningfully handle them. Obviously, (in my eyes > > > anyways), you shouldn't use them to just pass non-exceptional > > > information around. But there's a reason we have exceptions and a > > > framework that can catch and throw them. It can make error handling, > > > particularly when developing APIs, much more robust. > > > > > > > > > > > > --Ambrose > > > > > > On Mon, 13 Dec 2004 22:20:33 +0200, Justin Lovell <justin@(protected)> > > wrote: > > > > I would not like to use exceptions. It is generally bad that the > > exception > > > > could possibly fall through and on top of that, is kinda expensive > > > > to > > throw > > > > and catch. > > > > > > > > Have you considered using delegates (not events)? > > > > > > > > > > > > > > > > -----Original Message----- > > > > From: J. Ambrose Little [mailto:ambrogio@(protected)] > > > > Sent: 13 December 2004 08:40 PM > > > > To: aspnet-architecture@(protected) > > > > Subject: [aspnet-architecture] RE: Exception Handling Opinion > > > > > > > > Well, I don't think bubbling exceptions to the user is generally a > > > > good idea. If an exception occurs (bubbles to the UI tier), and the > > > > UI tier can't handle it gracefully, I let it bubble to the > > > > application > > > > level, which has the on error handler that logs/publishes the error > > > > to > > > > the appropriate place and redirects the user to an HTML error page > > > > that, obviously, just has a general error on it. You definitely do > > > > not want your users to see the exception details because that > > > > provides > > > > attackers with an insight into your app that you don't want them to > > > > have. > > > > > > > > If your UI tier can gracefully handle the exception, then I think it > > > > will be very context sensitive and not something that you can really > > > > standardarize on with a vanilla error page using message > > > > substitution. > > > > But if you want to do that, you can just use, e.g., a resources file > > > > and have a static function that you pass the exception to like > > > > GetDisplayMessage(Exception ex) that, based on the exception details > > > > (like type name), will pull an appropriate message from your > > > > resource > > > > file. > > > > > > > > --Ambrose > > > > > > > > On Mon, 13 Dec 2004 13:15:23 -0500, Tim Weaver > > > > <icodemarine@(protected)> > > > > wrote: > > > > > I've been going over something very similar. We already have an > > > > > infrastructure that allows customized messaging so the question > > > > > for > > us > > > > > what is the best way to get that message to the UI. The problem > > > > > with > > > > > exceptions is that we were seeing developers use: > > > > > catch(Exception ex) > > > > > { > > > > > string error = ex.Message; > > > > > } > > > > > and then add the error string to the page. This is a really > > > > > dangerous > > > > > way to go (IMO). There is no guarantee that the information > > > > > returned > > > > > from the message property should be shown to the user. It is a big > > > > > security risk to just blindly reflect error messages. > > > > > > > > > > The solution we ended up with is that we created custom > > > > > exception(s). > > > > > The base custom exception overrides the Message property and > > > > > returns > > > > > the "messagized" text. This way the developers can do > > > > > catch(SafeException ex) > > > > > { > > > > > string error = ex.Message; > > > > > > > > > > } > > > > > and always know that they will be given back text to show to the > > > > > end > > > > > user. They don't catch anything except the base exception and > > > > > those > > > > > derived from it. All other exceptions go to a generic error page > > > > > that > > > > > logs the issue and tells the user we had a problem. > > > > > > > > > > On Mon, 13 Dec 2004 11:39:41 -0500, Jason Gaylord > > > > > > > > > > > > > > > <jgaylord@(protected)> wrote: > > > > > > I am creating a new web application where I want to allow some > > > > > > end > > users > > > > to customize messages for specific business rules. For instance, if > > > > a > > user > > > > attempts to login, I want to kick off an exception. Then, the user > > would be > > > > shown a customized message. > > > > > > > > > > > > > > > > I figure I need an HttpHandler to effectively handle the message > > > > portion. However, I can't think of a good solution to raise an error > > > > or > > > > throw an exception. I have other exceptions such as a 404. > > > > > > > > > > > > Any suggestions? > > > > > > > > > > > > Best Regards, > > > > > > Jason N. Gaylord > > > > > > Microsoft MVP, ASPInsider > > > > > > http://www.jasongaylord.com > > > > > > jgaylord@(protected) > > > > > > --- > > > > > > [This E-mail scanned for viruses by Declude Virus] > > > > > > > > > > > > Need SQL Advice? http://sqladvice.com > > > > > > Need RegEx Advice? http://regexadvice.com > > > > > > Need XML Advice? http://xmladvice.com > > > > > > > > > > > > > > > > Need SQL Advice? http://sqladvice.com > > > > > Need RegEx Advice? http://regexadvice.com > > > > > Need XML Advice? http://xmladvice.com > > > > > > > > > > > > > -- > > > > J. Ambrose Little > > > > Microsoft ASP.NET MVP, ASPInsider > > > > http://dotNetTemplar.net > > > > > > > > Need SQL Advice? http://sqladvice.com > > > > Need RegEx Advice? http://regexadvice.com > > > > Need XML Advice? http://xmladvice.com > > > > --- > > > > > > > > > > > > [This E-mail scanned for viruses by Declude Virus] > > > > > > > > Need SQL Advice? http://sqladvice.com > > > > Need RegEx Advice? http://regexadvice.com > > > > Need XML Advice? http://xmladvice.com > > > > > > > > > > -- > > > J. Ambrose Little > > > Microsoft ASP.NET MVP, ASPInsider > > > http://dotNetTemplar.net > > > > > > Need SQL Advice? http://sqladvice.com > > > Need RegEx Advice? http://regexadvice.com > > > Need XML Advice? http://xmladvice.com > > > > > > > Need SQL Advice? http://sqladvice.com > > Need RegEx Advice? http://regexadvice.com > > Need XML Advice? http://xmladvice.com > > > > Need SQL Advice? http://sqladvice.com > > Need RegEx Advice? http://regexadvice.com > > Need XML Advice? http://xmladvice.com > > > > > -- > J. Ambrose Little > Microsoft ASP.NET MVP, ASPInsider > http://dotNetTemplar.net > > Need SQL Advice? http://sqladvice.com > Need RegEx Advice? http://regexadvice.com > Need XML Advice? http://xmladvice.com >
Need SQL Advice? http://sqladvice.com Need RegEx Advice? http://regexadvice.com Need XML Advice? http://xmladvice.com
|
|