473,486 Members | 2,353 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

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 1661
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
1657
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
1730
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
1093
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
2454
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
1444
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
1702
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
1265
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
3775
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
1506
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
7180
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...
1
6846
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...
0
7341
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...
1
4870
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
4564
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
3076
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
3071
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
1381
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 ...
0
266
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...

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.