D
dcassar
I have had a lively discussion with some coworkers and decided to get
some general feedback on an issue that I could find very little
guidance on. Why is it considered bad practice to define a public
member with a return type that is derived from System.Exception? I
understand the importance of having clean, concise code that follows
widely-accepted patterns and practices, but in this case, I find it
hard to blindly follow a standard when a better, more elegant solution
presents itself so readily.
I was writing a generic function to validate data that is going to be
used to represent key values for my business objects. It looked like
this:
public static ValidationException ValidateKeyArray(System.Type
targetType, object[] keys);
ValidationException is derived from ApplicationException, which, in
turn, derives from the base Exception class. The reason I chose to
write this in this way was to meet three requirements for this method:
a) Validation in itself should not throw an exception unless it cannot
figure out how to validate for some reason.
b) The code calling this method should be able to determine why
validation failed so it can either respond appropriately or throw an
exception if it can't recover
c) Figuring out why validation failed is not a separate logical process
from performing the validation itself, so it makes sense to have a
single function call to do both.
With the function written in this way (returning an object of type
ValidationException) I can:
1) Throw an exception if validation is impossible due to bad input, but
not have to throw an exception if the data is in the correct format but
is invalid
2) Return a descriptive error message in the ValidationException object
3) Return multiple error messages, if necessary (embedded in the
ValidationException object or attached to inner exceptions)
4) Avoid breaking normal program flow when validating, since failed
validation is not an error condition
5) Provide a throwable object to the caller so that critical validation
can be performed in two lines (ValidationException x =
ValidateKeyArray(type, array); if (x != null) throw x
As I understand them, the major alternatives are:
1) Returning a bool. This does not meet requirements (b) and (c).
2) Exposing validation information on the object, like the ASP.NET Page
object does. This would require a Validate method and an IsValid
property, and perhaps some sort of list to provide validation error
messages. This is considerably more code than the one I implemented,
and does not meet requirement (c). Also, validation exceptions would
not be standardized in any way, since I would be relying on the calling
code to throw an exception if it needs to.
3) Always throwing exceptions from the ValidateKeyArray method, and
relying on the caller to use a try...catch block to manage it. If you
know that the input could be bad, shouldn't you avoid throwing an
exception at all?
4) Returning some sort of non-Exception-derived class to expose the
results of validation. The only real disadvantage here is that it
requires some extra code to extract the message from this object and
then put it into an Exception if you need to throw it.
I am looking forward to hearing your thoughts.
Daniel
some general feedback on an issue that I could find very little
guidance on. Why is it considered bad practice to define a public
member with a return type that is derived from System.Exception? I
understand the importance of having clean, concise code that follows
widely-accepted patterns and practices, but in this case, I find it
hard to blindly follow a standard when a better, more elegant solution
presents itself so readily.
I was writing a generic function to validate data that is going to be
used to represent key values for my business objects. It looked like
this:
public static ValidationException ValidateKeyArray(System.Type
targetType, object[] keys);
ValidationException is derived from ApplicationException, which, in
turn, derives from the base Exception class. The reason I chose to
write this in this way was to meet three requirements for this method:
a) Validation in itself should not throw an exception unless it cannot
figure out how to validate for some reason.
b) The code calling this method should be able to determine why
validation failed so it can either respond appropriately or throw an
exception if it can't recover
c) Figuring out why validation failed is not a separate logical process
from performing the validation itself, so it makes sense to have a
single function call to do both.
With the function written in this way (returning an object of type
ValidationException) I can:
1) Throw an exception if validation is impossible due to bad input, but
not have to throw an exception if the data is in the correct format but
is invalid
2) Return a descriptive error message in the ValidationException object
3) Return multiple error messages, if necessary (embedded in the
ValidationException object or attached to inner exceptions)
4) Avoid breaking normal program flow when validating, since failed
validation is not an error condition
5) Provide a throwable object to the caller so that critical validation
can be performed in two lines (ValidationException x =
ValidateKeyArray(type, array); if (x != null) throw x

As I understand them, the major alternatives are:
1) Returning a bool. This does not meet requirements (b) and (c).
2) Exposing validation information on the object, like the ASP.NET Page
object does. This would require a Validate method and an IsValid
property, and perhaps some sort of list to provide validation error
messages. This is considerably more code than the one I implemented,
and does not meet requirement (c). Also, validation exceptions would
not be standardized in any way, since I would be relying on the calling
code to throw an exception if it needs to.
3) Always throwing exceptions from the ValidateKeyArray method, and
relying on the caller to use a try...catch block to manage it. If you
know that the input could be bad, shouldn't you avoid throwing an
exception at all?
4) Returning some sort of non-Exception-derived class to expose the
results of validation. The only real disadvantage here is that it
requires some extra code to extract the message from this object and
then put it into an Exception if you need to throw it.
I am looking forward to hearing your thoughts.
Daniel