473,837 Members | 1,531 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Exceptions as return values

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.Exceptio n? 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 ValidationExcep tion ValidateKeyArra y(System.Type
targetType, object[] keys);

ValidationExcep tion is derived from ApplicationExce ption, 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
ValidationExcep tion) 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 ValidationExcep tion object
3) Return multiple error messages, if necessary (embedded in the
ValidationExcep tion 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 (ValidationExce ption x =
ValidateKeyArra y(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 ValidateKeyArra y 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

Jan 9 '06
14 3486
"David Levine" <Sn************ *************@w i.rr.com> wrote in message
news:%2******** ********@TK2MSF TNGP15.phx.gbl. ..
I'd add one thing to your points. The OP stated he derived his exception
from the ApplicationExce ption class; I feel this is a rather useless
exception type; it does nothing to communicate the cause of an exception,
and it adds depth to the exception hierarchy but adds little of value. I
prefer to derive directly from Exception, or perhaps use a more
descriptive exception type, such as ArgumentExcepti on, rather then
ApplicationExce ption or a custom exception.


Being nitpicky...

User exceptions should derive from System.Applicat ionException, not
System.Exceptio n. See the Remarks section here in MSDN:
http://msdn.microsoft.com/library/de...classtopic.asp

To wit:
"This exception is provided as means to differentiate between exceptions
defined by applications versus exceptions defined by the system."

-- Alan
Jan 10 '06 #11
Alan Pretre wrote:
Being nitpicky...

User exceptions should derive from System.Applicat ionException, not
System.Exceptio n. See the Remarks section here in MSDN:
http://msdn.microsoft.com/library/de...classtopic.asp

To wit:
"This exception is provided as means to differentiate between exceptions
defined by applications versus exceptions defined by the system."


However, look at this:

http://blogs.msdn.com/brada/archive/.../25/96251.aspx
quoting the .NET Framework Standard Library Annotated Reference Vol 1:

<quote>
KC - Designing exception hierarchies is tricky. Well-designed exception
hierarchies are wide, not very deep, and contain only those exceptions
for which there is a programmatic scenario for catching. We added
ApplicationExce ption thinking it would add value by grouping exceptions
declared outside of the .NET Framework, but there is no scenario for
catching ApplicationExce ption and it only adds unnecessary depth to the
hierarchy.

JR - You should not define new exception classes derived from
Application-
Exception; use Exception instead. In addition, you should not write
code that
catches ApplicationExce ption.
</quote>

Jon

Jan 10 '06 #12
"Jon Skeet [C# MVP]" <sk***@pobox.co m> wrote in message
news:11******** *************@g 43g2000cwa.goog legroups.com...
<quote>
KC - Designing exception hierarchies is tricky. Well-designed exception
hierarchies are wide, not very deep, and contain only those exceptions
for which there is a programmatic scenario for catching. We added
ApplicationExce ption thinking it would add value by grouping exceptions
declared outside of the .NET Framework, but there is no scenario for
catching ApplicationExce ption and it only adds unnecessary depth to the
hierarchy.

JR - You should not define new exception classes derived from
Application-
Exception; use Exception instead. In addition, you should not write
code that
catches ApplicationExce ption.
</quote>


Hmmm.

Yes, I also see now that rule CA1058 in FxCop discourages deriving from
System.Applicat ionException as well. Funny, though, when you follow the
Error Raising and Handling Guidelines link in the FxCop rule, which is

http://msdn.microsoft.com/library/de...guidelines.asp

it says:

"Do not derive all new exceptions directly from the base class
SystemException . Inherit from SystemException only when creating new
exceptions in System namespaces. Inherit from ApplicationExce ption when
creating new exceptions in other namespaces."
Here is the FxCop rule:

Types should not extend certain base types
TypeName: TypesShouldNotE xtendCertainBas eTypes
CheckId: CA1058
Category: Microsoft.Desig n
Message Level: Error
Certainty: 75%
Breaking Change: Breaking

Cause: An externally visible type extends certain base types. Currently,
this rule reports types that derive from the following types:

a.. System.Applicat ionException
b.. System.Xml.XmlD ocument

Rule Description
For .NET Framework version 1, it was recommended to derive new exceptions
from ApplicationExce ption. The recommendation has changed and new exceptions
should derive from System.Exceptio n or one of its subclasses in the System
namespace. For more information, see Error Raising and Handling Guidelines

Do not create a subclass of XmlDocument if you want to create an XML view of
an underlying object model or data source.

How to Fix Violations
To fix a violation of this rule, derive the type from a different base type.

When to Exclude Messages
Do not exclude a message from this rule for violations concerning
ApplicationExce ption. It is safe to exclude a message from this rule for
violations about XmlDocument.

See Also
Error Raising and Handling Guidelines

-- Alan
Jan 10 '06 #13
Why not return a ValidationResul ts object rather than a
ValidationExcep tion. That could have a couple of key properties:
IsValid; Message; and perhaps ValidationExcep tion. So if a client
doesn't like it that a validation failed, it can do "throw
ValidationResul ts.ValidationEx ception". It's a little like your item
#4, but encapsulates the creation of the exception into the overall
results. This also allows for future enhancements. Perhaps you'll need
a Success, Warning, Error enum at some point. ValidationResul ts could
encapsulate this as well.

FWIW,

Donnie

Jan 11 '06 #14

dc*****@cmcdata works.com wrote:
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.Exceptio n?
Seems perfectly reasonable to me.
I
understand the importance of having clean, concise code that follows
widely-accepted patterns and practices,
Most people rarely see clean, concise code, so when they do see it, it
confuses them.
public static ValidationExcep tion ValidateKeyArra y(System.Type
targetType, object[] keys);
a) Validation in itself should not throw an exception unless it cannot
figure out how to validate for some reason.
ok...
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
perfectly logical, but I wonder what sort of recovery will be possible?
I would expect that any recovery rules would be closely related to the
validation rules.
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.
True.

With the function written in this way (returning an object of type
ValidationExcep tion) 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
It's not at all clear to me the difference between bad input and
invalid input -- they are just different kinds of badness.
2) Return a descriptive error message in the ValidationExcep tion object
3) Return multiple error messages, if necessary (embedded in the
ValidationExcep tion object or attached to inner exceptions)
4) Avoid breaking normal program flow when validating, since failed
validation is not an error condition
Throwing and catching exceptions allows separation of normal flow from
error flow. Returning a value which must be tested does not.
5) Provide a throwable object to the caller so that critical validation
can be performed in two lines (ValidationExce ption x =
ValidateKeyArra y(type, array); if (x != null) throw x;)
See, you've interrupted normal control flow with that test.

In general, returning values which must be tested by the caller is more
likely to lead to bugs than throwing an exception. If a caller forgets
to test a return value, then execution will proceed as though no error
occurred, even though an error has occurred, and potentially erroneous
results could be returned. But if an exception is uncaught, then
execution will terminate, and someone will know that something went
wrong.

As I understand them, the major alternatives are:

1) Returning a bool. This does not meet requirements (b) and (c).
I agree, this is much worse.
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.
Also horrible.
3) Always throwing exceptions from the ValidateKeyArra y 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?


I tend to prefer this solution, since it allows better separation of
the normal flow from the error flow. For most applications most of the
time the cost of throwing an exception is negligible. Certainly the
cost of throwing a single exception in a web method is epsilon compared
with the cost of the associated IO.

Jan 11 '06 #15

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

9
2344
by: Gianni Mariani | last post by:
I'm involved in a new project and a new member on the team has voiced a strong opinion that we should utilize exceptions. The other members on the team indicate that they have either been burned with unmaintainable code (an so are now not using exceptions). My position is that "I can be convinced to use exceptions" and my experience was that it let to code that was (much) more difficult to debug. The team decided that we'd give...
10
1555
by: Jakob Bieling | last post by:
Hi, somehow the prejudice of exceptions being rather slow (compared to, ie. returning an error value and checking that) keeps sticking around .. at least around me. I guess this is also why I refrained from using them often. But are they 'slow' in general? I guess it also depends on how, when and where you use them. What I am looking for is a sort of guideline that explains where exceptions are approriate and where they are not. The...
15
426
by: Bernard | last post by:
Hi All, I am not sure if I should be asking this question on clc or clc++. Let me try on both. I hope that this is not too trivial for the brilliant minds over here. I know that OOP questions have been asked on clc before so it is probably OK. I am a newbie to C++. BS 3rd edition states: % The throw transfers control to a handler for exceptions .... %
10
1303
by: Razzie | last post by:
Hi all, The title of this post may sound a bit weird, but I was wondering about the following nonetheless. I have a class libray containing, say, 4 classes: A, B, C, D. Class A somehow has a reference to B, B has a reference to C, and C to D. If an exception happens in class D, I would like class A to get a notification of this (all execution on classes B to D should be terminated). I am wondering how to do this. The following seems...
8
2263
by: cat | last post by:
I had a long and heated discussion with other developers on my team on when it makes sense to throw an exception and when to use an alternate solution. The .NET documentation recommends that an exception should be thrown only in exceptional situations. It turned out that each of my colleagues had their own interpretation about what an "exceptional situation" may actually be. First of all, myself I’m against using exceptions extensively,...
4
1857
by: Steve | last post by:
I have read a couple articles online, read my Jesse Liberty book but I am still confused as to just what the best practices are for using exceptions. I keep changing how I'm working with them and it has now, after 15k lines of code resulted in a royal mess! It's my hope to ask some specific questions with scenario examples and that some of you might offer a little guidance or general suggestions. 1) string...
42
3058
by: Jon Harrop | last post by:
Why are exceptions in C++ ~6x slower than exceptions in OCaml? -- Dr Jon D Harrop, Flying Frog Consultancy Objective CAML for Scientists http://www.ffconsultancy.com/products/ocaml_for_scientists/index.html?usenet
6
2054
by: Liming | last post by:
Hi, In a typical 3 tier model (view layer, busines layer and data access layer) where do you handle your exceptions? do you let it buble up all the way to the .aspx pages or do you handle it in your business layer and/or data access layer? suppose in my data access layer, I provide try and catch, log the exception and re-throw it back to business layer, then in yoru business layer, what do you do? throw it back to the code behind or...
17
1749
by: Christoph Zwerschke | last post by:
I'm just reading PEP 3107 (function annotations) and wonder why exceptions are not mentioned there. I think it would be helpful if one could specify which exceptions can be raised by a function, similarly to how it is possible in C++ using the "throw" clause. The syntax would be something like this: def foo(a: expr, b: expr = 5) raises expr -expr: The expr in that "raises" clause should be a list of Exceptions.
0
9837
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, well explore What is ONU, What Is Router, ONU & Routers main usage, and What is the difference between ONU and Router. Lets take a closer look ! Part I. Meaning of...
0
9682
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10870
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10563
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
10621
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
10267
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
5845
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4474
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
3
3123
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.