deft flux

A portal into the creative workings of David Meyer

About the author

David Meyer (a.k.a. "deft flux") is a software developer fluent in C#, C++, Java and others. He also programs in his spare time and enjoys playing instruments and making electronic music.
E-mail me Send mail

Recent posts

Recent comments

Authors

Disclaimer

The opinions expressed by the author are his alone and do not represent any other person or organization unless stated otherwise. The opinions given in comments are solely those of the person who wrote the comment and are not necessarily the opinions of the author of this site. The author of a post is not responsible for the content of its comments.

© Copyright 2008
David Meyer

Safe execution or easier debugging?

I'm talking about exceptions here.  Which is better, avoiding throwing exceptions as much as possible by trying to safely recover from errors, or throwing exceptions that will contain useful information for debugging purposes?  I ran into this issue today...

The company I work for uses a program called Fourth Shift.  It comes with managed libraries for client access in .NET.  I am using a feature called impersonation, whereby transactions can be executed as if a different user was logged in.  There are a few things you have to do in order for this to work:

  • Grant the logged in user permission to impersonate a given user.
  • Enable impersonation when connecting the client.
  • Supply a non-null impersonation user name when processing a transaction.

I had to figure all this out because the developers of the client library decided to go with safe execution.  Here's what will happen if the above conditions are not met:

  • If the user does not have permission to impersonate the given user, the transaction will proceed normally without impersonation.  No exception will be thrown.
  • If impersonation is not enabled but a non-null impersonation user name is supplied, the transaction will proceed normally without impersonation.  No exception will be thrown.

This behavior is about as useful for debugging as the "Failed for some reason" exception message I ranted about in an earlier post, which involved the same client library I might add.  All I knew was that for some reason impersonation was not taking place.  In any case, here is the behavior I would normally expect from a .NET class library:

  • If the user does not have permission to impersonate the given user, an exception is thrown indicating this.
  • If impersonation is not enabled but a non-null impersonation user name is supplied, an exception is thrown indicating this.

Now sure, this would help debugging immensely, but won't it make the program less stable?  Well, in the case of the latter, no.  Whether or not impersonation is enabled is hard-coded and will not change at run-time.  It will either always throw an exception (not work at all) or never throw one (always work).  In the case of the former, do we want the transaction to succeed if the user does not have permission to impersonate?  Sure, if they don't, the program will fail, but at least we'll know exactly why and it's a no-brainer to fix.  Another thing to consider is security.  If impersonation does not take place, the transaction will be executed under the security context of the logged in user, which in this case, most likely has more security rights than the user that should be impersonated.

So in this case, I would say throwing exceptions would be a better approach.  But is it always?  Or is this one of those trade-offs like high cohesion vs. low coupling that needs to be weighed in every design?  Or is there a way to have both safe execution and easy debugging?

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Categories: Development
Posted by deftflux on Friday, May 09, 2008 3:50 PM
Permalink | Comments (1) | Post RSSRSS comment feed

Related posts

Comments

Jeremy Gray ca

Saturday, May 10, 2008 4:40 PM

Gravatar

The fundamental problem with "safe" code like that is that it is far from "safe", and debugging is only the smallest of the problems. Code that doesn't "fail fast", specifically through the throwing of exceptions, starts a team down a path of all sorts of creative error detection and recovery and vastly more complicated testing requirements due to having to generate tests not just around the failure cases but also the much more complicated recovery from them. Never mind that future development is made more complicated due to how much more difficult it is to know whether or not your application has gotten into some kind of nasty, unknown (and therefore unsafe to recover from) state when it really should have failed fast.

As far as I'm concerned, there are four operating modes that all code can be classified in:
1. Success
2. Recover from "failures" determinable in advance by nothing but business rules
3. Fast failure through exceptions
4. Recovery from an extremely small, extremely well-defined, extremely well-implemented (in that they leave the app in a well-proven good state) set of "expected exceptions" ala the TImeoutException of WCF.

The only way to keep things in check is to make sure that #2 is minimized to only those "failures" that truly can be avoided in advance through pure business rules, and that #4 is minimized to an extremely small set of cases, lest the #3s start slipping in and all sorts of crazy recovery code starts showing up and having to be debugged, tested, and maintained with far more effort.

Add comment


(Will show your Gravatar icon)  

  Country flag




Live preview

Thursday, August 21, 2008 2:56 AM

Gravatar