473,387 Members | 1,492 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

Proper use of inner exceptions

Hi group,

I am quite new to exceptions in .NET and I am a bit confused of how to
use the inner exceptions. Could anyone explain? Let's say I have a
function that takes a double (X) that is not supposed to be less or
equal to zero. Let's call this function DoSomething.

Also let's say that this function in turn calls another function doing
something with X.

Then if there is a bug in the DoSomething function that causes the
other function to throw an ArgumentOutOfRangeException.

void DoSomething(double X)
{
if(X<=0)
throw new ArgumentOutOfRangeException("X","X has to be greater
than zero");
X-=10; // This is a bug..
AnotherFunction(X);
}

void AnotherFunction(double X)
{
if(X<=0)
throw new ArgumentOutOfRangeException("X"," X has to be
greater than zero ");
Jul 21 '05 #1
7 1658
Kenny,
Ok, now if I call DoSomething with 10 or less I will get an
ArgumentOutOfRangeException. Then I will think that this is because I
called DoSomething with a value of X less or equal to zero.


Not if you examine the exception's StackTrace, it will tell you that
it originated from AnotherFunction.

Mattias

--
Mattias Sjögren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.
Jul 21 '05 #2
IMO :
- there is no need to try to catch this situation, just correct the bug
- if DoSomething requires x<=0 because it calls AnotherFunction that
requires x<=0, don't catch the exception in DoSomething. IMO the exception
just be thrown exactly where your requirement is no met.
- an exception is to catch programming or environment error. Here I would
validate the user input before calling the function.

Patrice
--

"Kenny Cutter" <st***@cncsimulator.com> a écrit dans le message de
news:83**************************@posting.google.c om...
Hi group,

I am quite new to exceptions in .NET and I am a bit confused of how to
use the inner exceptions. Could anyone explain? Let's say I have a
function that takes a double (X) that is not supposed to be less or
equal to zero. Let's call this function DoSomething.

Also let's say that this function in turn calls another function doing
something with X.

Then if there is a bug in the DoSomething function that causes the
other function to throw an ArgumentOutOfRangeException.

void DoSomething(double X)
{
if(X<=0)
throw new ArgumentOutOfRangeException("X","X has to be greater
than zero");
X-=10; // This is a bug..
AnotherFunction(X);
}

void AnotherFunction(double X)
{
if(X<=0)
throw new ArgumentOutOfRangeException("X"," X has to be
greater than zero ");
.
.
// Do something with X
}

Ok, now if I call DoSomething with 10 or less I will get an
ArgumentOutOfRangeException. Then I will think that this is because I
called DoSomething with a value of X less or equal to zero.

try
{
double x= getValueFromUser();
DoSomething(X);
}
catch(ArgumentOutOfRangeException e)
{
MessageBox.Show("Dear User, please enter a value greater than 0");
}

But the problem here was not the input from the user but the bug in
DoSomething...

So what is the correct use of exceptions/innerexceptions? Should I
instead change the DoSomething to catch exceptions and rethrow them as
inner exceptions in an own exception type? Like this?

void DoSomething(double X)
{
if(X<=0)
throw new ArgumentOutOfRangeException("X","X is to small");
X-=10; // This is a bug..
try
{
AnotherFunction(X);
}
catch(ArgumentOutOfRangeException e)
{
MyOwnException myex = new MyOwnException("Call to
AnotherFunction failed",e); // Set innerexception as e
}
}

or should I catch all exceptions that AnotherFunction could throw
(catch the exceptions base type) and rethrow them as my own exception
with the innerexception set to the original exception?

Does this mean that in all assemblies that I write, in all public
functions, I should catch all exceptions and rethrow them as my own
exceptions with the innerexceptions set to the original exception? Or
have I missed something here, is there another approach to avoid the
problem above?

Any help to make me see this clearer is highly appreciated.

/kenny

Jul 21 '05 #3
Hello Kenny,

There have been a few online articles and blogs on "best practices" in .Net
exception handling, so I'd suggest you start there.
This topic has been discussed here many times before.

In a nutshell:
a) catch the error as close to the point where it triggered as possible,
b) log the event
c) respond appropriately so no system state is corrupted or memory is lost,
d) then, if the downstream error means that your current method cannot
perform its responsibilities in a way that gracefully handles the error, you
return a new exception containing the old one as an inner exeption.

80% of the time, you will not create a new exception to contain the old one.
Also, it is perfectly OK to throw a new ApplicationException() containing
your embedded exception... you don't need to create a custom exception class
for every possible exception. (If you have an entire "class" of exceptions,
then you can benefit from the custom exception type).

--
--- Nick Malik [Microsoft]
MCSD, CFPS, Certified Scrummaster
http://blogs.msdn.com/nickmalik

Disclaimer: Opinions expressed in this forum are my own, and not
representative of my employer.
I do not answer questions on behalf of my employer. I'm just a
programmer helping programmers.
--
"Kenny Cutter" <st***@cncsimulator.com> wrote in message
news:83**************************@posting.google.c om...
Hi group,

I am quite new to exceptions in .NET and I am a bit confused of how to
use the inner exceptions. Could anyone explain? Let's say I have a
function that takes a double (X) that is not supposed to be less or
equal to zero. Let's call this function DoSomething.

Also let's say that this function in turn calls another function doing
something with X.

Then if there is a bug in the DoSomething function that causes the
other function to throw an ArgumentOutOfRangeException.

void DoSomething(double X)
{
if(X<=0)
throw new ArgumentOutOfRangeException("X","X has to be greater
than zero");
X-=10; // This is a bug..
AnotherFunction(X);
}

void AnotherFunction(double X)
{
if(X<=0)
throw new ArgumentOutOfRangeException("X"," X has to be
greater than zero ");
.
.
// Do something with X
}

Ok, now if I call DoSomething with 10 or less I will get an
ArgumentOutOfRangeException. Then I will think that this is because I
called DoSomething with a value of X less or equal to zero.

try
{
double x= getValueFromUser();
DoSomething(X);
}
catch(ArgumentOutOfRangeException e)
{
MessageBox.Show("Dear User, please enter a value greater than 0");
}

But the problem here was not the input from the user but the bug in
DoSomething...

So what is the correct use of exceptions/innerexceptions? Should I
instead change the DoSomething to catch exceptions and rethrow them as
inner exceptions in an own exception type? Like this?

void DoSomething(double X)
{
if(X<=0)
throw new ArgumentOutOfRangeException("X","X is to small");
X-=10; // This is a bug..
try
{
AnotherFunction(X);
}
catch(ArgumentOutOfRangeException e)
{
MyOwnException myex = new MyOwnException("Call to
AnotherFunction failed",e); // Set innerexception as e
}
}

or should I catch all exceptions that AnotherFunction could throw
(catch the exceptions base type) and rethrow them as my own exception
with the innerexception set to the original exception?

Does this mean that in all assemblies that I write, in all public
functions, I should catch all exceptions and rethrow them as my own
exceptions with the innerexceptions set to the original exception? Or
have I missed something here, is there another approach to avoid the
problem above?

Any help to make me see this clearer is highly appreciated.

/kenny

Jul 21 '05 #4
Kenny,

Nick Malik is right: there are a lot of 'blog articles, online
whitepapers, and even books on the subject of properly handling
exceptions. Here are a few places to start:

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

http://msdn.microsoft.com/msdnmag/is...T/default.aspx

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

However, all of this won't stop me from adding my two cents' worth. :)
The philosophy you stated in your opening question is along the right
lines. To my thinking, the purpose of inner exceptions is to transform
exceptions that you know may happen in your method into terms that make
sense to callers.

For example, if you were to require that your argument X be non-zero,
because your method is going to try to divide by X, it would be very
bad form to simply let the method throw a DivideByZeroException. From
the caller's point of view, this is meaningless. The caller has to
understand the inner workings of your method in order to interpret the
exception.

Now, whether you choose to test for X == 0 and throw an
InvalidArgumentException, or catch the DivideByZeroException and wrap
it in an InvalidArgumentException is up to you. Most people would do
the former, but you could do the latter if the information about where
the divide by zero happened was of interest and you didn't want to lose
it.

In cases in which you call other methods that throw exceptions, you may
have no choice but to catch them, and then you may wish to transform
them into terms more meaningful to your callers. In these cases you
almost certainly want to wrap them as inner exceptions.

Jul 21 '05 #5
Not to put too fine a point on it:
a double divided by a double won't throw a DivideByZeroException...

Jul 21 '05 #6
Ola
Hi.

I have the same kind of questions as Kenny.
Anyone got some more useful links to help me learn how to properly
handle exceptions.
A link to a good discussion in the subject would be nice.
Jul 21 '05 #7
There have been a few online articles and blogs on "best practices" in
.Net
exception handling, so I'd suggest you start there.
This topic has been discussed here many times before.

In a nutshell:
a) catch the error as close to the point where it triggered as possible,
b) log the event
Usually a good idea, but this may not be the correct action to take - it
depends on the system. The issue of where logging should occur needs to
account for intermediate routines that catch-wrap-throw. You would not want
intermediate catch blocks to also log the exception - it would quickly
overwhelm the logging system with redundant data. I prefer to log it once at
the original exception site, and then log it again at a boundary across
which the exception will propagate. I usually define the boundary as the
edge of a web service, process or appdomain.
c) respond appropriately so no system state is corrupted or memory is
lost,
Easier said then done. Implementing complete rollback semantics across all
objects, external data stores, etc. is non-trivial - in some cases it may
not even be possible. These potential corruption points should be defined
and known.
d) then, if the downstream error means that your current method cannot
perform its responsibilities in a way that gracefully handles the error,
you
return a new exception containing the old one as an inner exeption.

80% of the time, you will not create a new exception to contain the old
one.
Also, it is perfectly OK to throw a new ApplicationException() containing
your embedded exception... you don't need to create a custom exception
class
for every possible exception.
As an alternative to using the generic ApplicationException you can throw
the same exception type as the that was caught (clone it). Also, the use of
the ApplicationException type is being discouraged by new MSFT guidelines.

There has also been discussions around the distinction between technical
exceptions and business logic exceptions. Typical usage is for low-level
code to either handle faults or propagate technical exceptions upwards, and
higher level logic then provides a translation layer that maps these into
business logic exceptions that are more understandable to users. In other
words, presenting a user with a null reference exception doesn't help them
much - telling them to enter a valid user name does.
(If you have an entire "class" of exceptions,
then you can benefit from the custom exception type).
There are downsides, mainly with versioning and system evolution, and
propagating exceptions across process boundaries. I would discourage
allowing a custom exception to propagate outside of a web service - the
client may not be able to deserialize it. This may not be an issue for
small, self-contained systems, but for distributed systems, either using web
services, remoting, or multiple appdomains, it can be a problem.


--
--- Nick Malik [Microsoft]
MCSD, CFPS, Certified Scrummaster
http://blogs.msdn.com/nickmalik

Jul 21 '05 #8

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

Similar topics

5
by: Pekka Niiranen | last post by:
Hi, I have Perl code looping thru lines in the file: line: while (<INFILE>) { ... $_ = do something ... if (/#START/) { # Start inner loop
7
by: Kenny Cutter | last post by:
Hi group, I am quite new to exceptions in .NET and I am a bit confused of how to use the inner exceptions. Could anyone explain? Let's say I have a function that takes a double (X) that is not...
2
by: a_newcomb | last post by:
I am using a HttpWebRequest object to a custom webhandler. When processing the request on the server side, I need to return exceptions to the web request. Whenever the exceptions are thrown, web...
2
by: Sue | last post by:
I've got a simple Application_OnError routine set up as a generic error trap for web applications running on IIS server (VS 2003) that logs error info and the text of the first inner exception....
4
by: CK | last post by:
Good Morning, I have a person table with personID. I have a personRate table with personID, rateID, and effectiveDate. I need to select fields from personRate, but I want the fields from the...
6
by: Lance | last post by:
hi all, using the following code, i never get a message box showing the error, but the default error sound is produced (like there should be an accompanying messagebox). \\\\\\\\\\ Dim FI As...
14
by: John Salerno | last post by:
Hi guys. I was wondering if someone could suggest some possible structures for an "Education" table in a database. It will contain at minimum university names, years of attendance, and degrees...
5
by: Thomas Guettler | last post by:
Hi, How can you get the traceback of the inner exception? try: try: import does_not_exit except ImportError: raise Exception("something wrong") except:
1
nurikoAnna
by: nurikoAnna | last post by:
how to properly separate sql codes........ I am using &_ as a separator...because it will not suits the visual basic code form...it will skip to the next line that's why I am having trouble in it...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
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,...
0
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...
0
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...

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.