473,881 Members | 1,641 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Some questions about handling exceptions and when to throw them

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 GetCustomerFirm warePath(string serialNumber) - This is a method
in a class library I have written and it is called from my UI "Presenter"
class' (In case you aren't familiar, Model View Presenter is very similar
to Model View Controller pattern). In the event that a customer can't be
located from the serialNumber parameter, is it a better choice to return
null and check for it or to throw an exception from
GetCustomerFirm warePath()? Possibly even my own exception, IE:
"CustomerNotFou ndException"? I have read that exceptions shouldn't be used
for logic, but I have been spending a lot of time with the Patterns and
Practices group's Composite Application Block and in one of the examples,
they use exceptions in this manner.

2) methodA calls MethodB which calls MethodC, MethodD and MethodE. IE:
PrinterInfo GetEmployeeDefa ultPrinter(stri ng employeeFullNam e)
calls EmployeeInfo GetEmployeeInfo (employeeFullNa me)
calls ComputerInfo GetEmployeeComp uterInfo(Employ eeInfo info)
returns ComputerInfo.De faultPrinter

So that is a massively stupid design, but I couldn't think of an example
that is easy to visualize (mine is very confusing and wouldn't be a good
example) Point is, if the call to GetEmployeeComp uterInfo fails, there is
no clean way to return that error back from GetEmployeeDefa ultPrinter() or
if the call to GetEmployeeInfo () fails, same thing. I can return null all
the back down the stack, but short of looking at the log (assuming I'm
logging) there is no clean way to determine where the problem was. This
example makes me think that throwing an "ComputerInfoNo tFoundException "
might be a good idea, then I could could catch it in GetEmployeeInfo and
throw a "EmployeeInfoNo tFound" exception with the
"ComputerInfoNo tFoundException " as the inner exception. Does that makes
sense? Is it a good design? Seems like a lot of exceptions! But what
other clean way could you handle this? Please don't suggest anything like
overriding GetEmployeeComp uterInfo(string employeeFullNam e) and avoiding the
whole call stack, it's just an example, my actual situation has a good
reason for breaking things apart like this.

3) How do you decide what exceptions to catch and which ones not to? I
have read that if I know I can handle it(IE: FileNotFound) then I can catch
it and act accordingly, but that would suggest that it's OK to let all
others bubble up... bubble up to where? Application.Run ()? What guidelines
are there?

4) One last one. As I think I mentioned earlier, I'm using the Composite
Application Block. Using the CAB encourages breaking logic into separate
assemblies to be shared by other assemblies for code reuse, etc. There is a
concept of a "Service" which is a basically a singleton that will perform
tasks related to a Workitem. For example, I have a service called
"FirmwareServic e" and it is responsible for adding new versions of firmware
for our products to the database, retrieving older version, assigning a
particular version to specific customers, etc, etc. An example method is:
string GetCustomerFirm warePath(Custom er customer);
This function is similiar to GetEmployeeDefa ultPrinter() in that it makes a
lot of other calls that could result in an error, either acceptable or
fatal. What I have tried to do in my design is avoid having code like this
scattered throughout my Presenters and other task code:
<code>
// Presenter method to get a customer's firmware path and display in the
view
// All manufactured products have a record of what customer they are for
and from that, what firmware should be loaded
ProductInfo productInfo =
_productionServ ice.GetProductR ecordFromSerial Num(serialNumbe r);
if(productInfo == null)
{
// show error
return false;
}

Customer customer = _firmwareServic e.GetCustomerFr omProductInfo(p roductInfo
;
if(customer == null)
{
// show an error
return false;
}

string firmwarePath = _firmwareServic e.GetCustomerFi rmwarePath(cust omer);
if(firmwarePath == null || firmwarePath.Le ngth < 1)
{
// show an error
return false;
}
</code>

(that was not real code, so if there are errors, please excuse me)

What I DO want to have is something like this:
<code>
string firmwarePath =
_firmwareServic e.GetFirmwarePa thFromSerialNum (serialNum);
if(firmwarePath == null || firmwarePath.Le ngth < 1)
{
// show an error
return false;
}
</code>

This question is ending up to be a duplicate of #2, but I guess that is my
main question. Given the example above assuming that
GetFirmwarePath FromSerialNum() performs all the tasks in the example code
before it, how do gracefully return errors and handle the exceptions? For
example, if the Customer record was found but not the firmware path, I might
want to do something like allow the user to add firmware for the customer or
something... I dunno, I've written too much, I'll stop.

Hopefully someone will take notice of this very long email and respond with
some insights for me :0)

Thanks for reading,
Steve
Jul 7 '06 #1
4 1858
V
Steve,

I will attempt to answer your questions based on what I get implemented
in our projects at work:

1. NO, you should not be using exceptions for Logic in your code. As
for the Application Block, those are more like an extension to the
framework, and are meant to be used by loads of developers. Its like
the framework throwing exception on illeagal use of a class. Not
finding a customer is by no means an illegal use of a class.
Additionally, this code is your own and for your own consumption, so
you should not be using exceptions to drive application logic.

2. For a scenario like this, you can always examine the stack trace
property of an exception to determine where the exception actually
happened. Another way for this is to build up a system of status codes,
and return status codes instead of exceptions to pass information up a
stack.

3. The way I tell my developers is: Catch any exception that you can
imagine occuring and can therefore handle. By handle, I mean that the
exception can be caught and an alternative action can be taken to
address the situation. This could simply even mean building up correct
error messages, or it could mean triggering some other program logic.
As a rule, a global exception handler should be present which catches
all exceptions (which you may not be handling), and handles them, and
logs them, etc.

4. Once again, build a status code framework for usage across your app.

- Vaibhav
Steve wrote:
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 GetCustomerFirm warePath(string serialNumber) - This is a method
in a class library I have written and it is called from my UI "Presenter"
class' (In case you aren't familiar, Model View Presenter is very similar
to Model View Controller pattern). In the event that a customer can't be
located from the serialNumber parameter, is it a better choice to return
null and check for it or to throw an exception from
GetCustomerFirm warePath()? Possibly even my own exception, IE:
"CustomerNotFou ndException"? I have read that exceptions shouldn't be used
for logic, but I have been spending a lot of time with the Patterns and
Practices group's Composite Application Block and in one of the examples,
they use exceptions in this manner.

2) methodA calls MethodB which calls MethodC, MethodD and MethodE. IE:
PrinterInfo GetEmployeeDefa ultPrinter(stri ng employeeFullNam e)
calls EmployeeInfo GetEmployeeInfo (employeeFullNa me)
calls ComputerInfo GetEmployeeComp uterInfo(Employ eeInfo info)
returns ComputerInfo.De faultPrinter

So that is a massively stupid design, but I couldn't think of an example
that is easy to visualize (mine is very confusing and wouldn't be a good
example) Point is, if the call to GetEmployeeComp uterInfo fails, there is
no clean way to return that error back from GetEmployeeDefa ultPrinter() or
if the call to GetEmployeeInfo () fails, same thing. I can return null all
the back down the stack, but short of looking at the log (assuming I'm
logging) there is no clean way to determine where the problem was. This
example makes me think that throwing an "ComputerInfoNo tFoundException "
might be a good idea, then I could could catch it in GetEmployeeInfo and
throw a "EmployeeInfoNo tFound" exception with the
"ComputerInfoNo tFoundException " as the inner exception. Does that makes
sense? Is it a good design? Seems like a lot of exceptions! But what
other clean way could you handle this? Please don't suggest anything like
overriding GetEmployeeComp uterInfo(string employeeFullNam e) and avoiding the
whole call stack, it's just an example, my actual situation has a good
reason for breaking things apart like this.

3) How do you decide what exceptions to catch and which ones not to? I
have read that if I know I can handle it(IE: FileNotFound) then I can catch
it and act accordingly, but that would suggest that it's OK to let all
others bubble up... bubble up to where? Application.Run ()? What guidelines
are there?

4) One last one. As I think I mentioned earlier, I'm using the Composite
Application Block. Using the CAB encourages breaking logic into separate
assemblies to be shared by other assemblies for code reuse, etc. There is a
concept of a "Service" which is a basically a singleton that will perform
tasks related to a Workitem. For example, I have a service called
"FirmwareServic e" and it is responsible for adding new versions of firmware
for our products to the database, retrieving older version, assigning a
particular version to specific customers, etc, etc. An example method is:
string GetCustomerFirm warePath(Custom er customer);
This function is similiar to GetEmployeeDefa ultPrinter() in that it makes a
lot of other calls that could result in an error, either acceptable or
fatal. What I have tried to do in my design is avoid having code like this
scattered throughout my Presenters and other task code:
<code>
// Presenter method to get a customer's firmware path and display in the
view
// All manufactured products have a record of what customer they are for
and from that, what firmware should be loaded
ProductInfo productInfo =
_productionServ ice.GetProductR ecordFromSerial Num(serialNumbe r);
if(productInfo == null)
{
// show error
return false;
}

Customer customer = _firmwareServic e.GetCustomerFr omProductInfo(p roductInfo
;
if(customer == null)
{
// show an error
return false;
}

string firmwarePath = _firmwareServic e.GetCustomerFi rmwarePath(cust omer);
if(firmwarePath == null || firmwarePath.Le ngth < 1)
{
// show an error
return false;
}
</code>

(that was not real code, so if there are errors, please excuse me)

What I DO want to have is something like this:
<code>
string firmwarePath =
_firmwareServic e.GetFirmwarePa thFromSerialNum (serialNum);
if(firmwarePath == null || firmwarePath.Le ngth < 1)
{
// show an error
return false;
}
</code>

This question is ending up to be a duplicate of #2, but I guess that is my
main question. Given the example above assuming that
GetFirmwarePath FromSerialNum() performs all the tasks in the example code
before it, how do gracefully return errors and handle the exceptions? For
example, if the Customer record was found but not the firmware path, I might
want to do something like allow the user to add firmware for the customer or
something... I dunno, I've written too much, I'll stop.

Hopefully someone will take notice of this very long email and respond with
some insights for me :0)

Thanks for reading,
Steve
Jul 7 '06 #2
Hi Vaibhav,

Thank you very much for taking the time to respond, I will review your
answers a couple more times and think about ways I can adapt some of your
suggestions.

I never thought of status codes and when I do think of them it reminds me of
older libraries and APIs I have used, they just don't feel "Latest and
greatest", but I know that doesn't mean it's not a good solution. I think I
will try implementing them in a single library and go form there.

Thanks again,
Steve
"V" <va************ *@gmail.comwrot e in message
news:11******** *************@7 5g2000cwc.googl egroups.com...
Steve,

I will attempt to answer your questions based on what I get implemented
in our projects at work:

1. NO, you should not be using exceptions for Logic in your code. As
for the Application Block, those are more like an extension to the
framework, and are meant to be used by loads of developers. Its like
the framework throwing exception on illeagal use of a class. Not
finding a customer is by no means an illegal use of a class.
Additionally, this code is your own and for your own consumption, so
you should not be using exceptions to drive application logic.

2. For a scenario like this, you can always examine the stack trace
property of an exception to determine where the exception actually
happened. Another way for this is to build up a system of status codes,
and return status codes instead of exceptions to pass information up a
stack.

3. The way I tell my developers is: Catch any exception that you can
imagine occuring and can therefore handle. By handle, I mean that the
exception can be caught and an alternative action can be taken to
address the situation. This could simply even mean building up correct
error messages, or it could mean triggering some other program logic.
As a rule, a global exception handler should be present which catches
all exceptions (which you may not be handling), and handles them, and
logs them, etc.

4. Once again, build a status code framework for usage across your app.

- Vaibhav
Steve wrote:
>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 GetCustomerFirm warePath(string serialNumber) - This is a
method
in a class library I have written and it is called from my UI "Presenter"
class' (In case you aren't familiar, Model View Presenter is very
similar
to Model View Controller pattern). In the event that a customer can't be
located from the serialNumber parameter, is it a better choice to return
null and check for it or to throw an exception from
GetCustomerFir mwarePath()? Possibly even my own exception, IE:
"CustomerNotFo undException"? I have read that exceptions shouldn't be
used
for logic, but I have been spending a lot of time with the Patterns and
Practices group's Composite Application Block and in one of the examples,
they use exceptions in this manner.

2) methodA calls MethodB which calls MethodC, MethodD and MethodE. IE:
PrinterInfo GetEmployeeDefa ultPrinter(stri ng employeeFullNam e)
calls EmployeeInfo GetEmployeeInfo (employeeFullNa me)
calls ComputerInfo GetEmployeeComp uterInfo(Employ eeInfo info)
returns ComputerInfo.De faultPrinter

So that is a massively stupid design, but I couldn't think of an example
that is easy to visualize (mine is very confusing and wouldn't be a good
example) Point is, if the call to GetEmployeeComp uterInfo fails, there
is
no clean way to return that error back from GetEmployeeDefa ultPrinter()
or
if the call to GetEmployeeInfo () fails, same thing. I can return null
all
the back down the stack, but short of looking at the log (assuming I'm
logging) there is no clean way to determine where the problem was. This
example makes me think that throwing an "ComputerInfoNo tFoundException "
might be a good idea, then I could could catch it in GetEmployeeInfo and
throw a "EmployeeInfoNo tFound" exception with the
"ComputerInfoN otFoundExceptio n" as the inner exception. Does that makes
sense? Is it a good design? Seems like a lot of exceptions! But what
other clean way could you handle this? Please don't suggest anything
like
overriding GetEmployeeComp uterInfo(string employeeFullNam e) and avoiding
the
whole call stack, it's just an example, my actual situation has a good
reason for breaking things apart like this.

3) How do you decide what exceptions to catch and which ones not to? I
have read that if I know I can handle it(IE: FileNotFound) then I can
catch
it and act accordingly, but that would suggest that it's OK to let all
others bubble up... bubble up to where? Application.Run ()? What
guidelines
are there?

4) One last one. As I think I mentioned earlier, I'm using the
Composite
Application Block. Using the CAB encourages breaking logic into separate
assemblies to be shared by other assemblies for code reuse, etc. There
is a
concept of a "Service" which is a basically a singleton that will perform
tasks related to a Workitem. For example, I have a service called
"FirmwareServi ce" and it is responsible for adding new versions of
firmware
for our products to the database, retrieving older version, assigning a
particular version to specific customers, etc, etc. An example method
is:
string GetCustomerFirm warePath(Custom er customer);
This function is similiar to GetEmployeeDefa ultPrinter() in that it makes
a
lot of other calls that could result in an error, either acceptable or
fatal. What I have tried to do in my design is avoid having code like
this
scattered throughout my Presenters and other task code:
<code>
// Presenter method to get a customer's firmware path and display in the
view
// All manufactured products have a record of what customer they are for
and from that, what firmware should be loaded
ProductInfo productInfo =
_productionSer vice.GetProduct RecordFromSeria lNum(serialNumb er);
if(productIn fo == null)
{
// show error
return false;
}

Customer customer =
_firmwareServi ce.GetCustomerF romProductInfo( productInfo
;
if(customer == null)
{
// show an error
return false;
}

string firmwarePath = _firmwareServic e.GetCustomerFi rmwarePath(cust omer);
if(firmwarePat h == null || firmwarePath.Le ngth < 1)
{
// show an error
return false;
}
</code>

(that was not real code, so if there are errors, please excuse me)

What I DO want to have is something like this:
<code>
string firmwarePath =
_firmwareServi ce.GetFirmwareP athFromSerialNu m(serialNum);
if(firmwarePat h == null || firmwarePath.Le ngth < 1)
{
// show an error
return false;
}
</code>

This question is ending up to be a duplicate of #2, but I guess that is
my
main question. Given the example above assuming that
GetFirmwarePat hFromSerialNum( ) performs all the tasks in the example code
before it, how do gracefully return errors and handle the exceptions?
For
example, if the Customer record was found but not the firmware path, I
might
want to do something like allow the user to add firmware for the customer
or
something... I dunno, I've written too much, I'll stop.

Hopefully someone will take notice of this very long email and respond
with
some insights for me :0)

Thanks for reading,
Steve

Jul 7 '06 #3
Steve wrote:
1) string GetCustomerFirm warePath(string serialNumber) - <snip>
In the event that a customer can't be
located from the serialNumber parameter, is it a better choice to return
null and check for it or to throw an exception from
GetCustomerFirm warePath()? Possibly even my own exception, IE:
"CustomerNotFou ndException"? I have read that exceptions shouldn't be used
for logic, but I have been spending a lot of time with the Patterns and
Practices group's Composite Application Block and in one of the examples,
they use exceptions in this manner.
This very much depends upon context, and so looking at the method in
isolation, there's no right answer. Since you have the luxury of both
writing the method and writing its caller, you may be able to make a
definitive choice.

The way to decide is to ask yourself whether not finding a customer for
that serial number is something that should "never happen", or
something that is a common possibility. If it's the former, then an
exception is an appropriate choice; if it's the latter then you should
do one of two things:

1. Return null, but this works only if there's only one error
condition, or there are multiple error conditions but you don't need to
distinguish between them, so there's only one error condition at the
level of GetCustomerFirm warePath, conceptually speaking, or

2. Provide another method that will check for the error condition, and
then make GetCustomerFirm warePath fail with an exception. So, you might
right CustomerHasFirm warePath, which returns true or false, and then
GetCustomerFirm warePath will die with an exception if there is no
customer, because the caller should have checked first. See the
Framework's TryParse / Parse methods to see this in action.
2) methodA calls MethodB which calls MethodC, MethodD and MethodE. IE:
PrinterInfo GetEmployeeDefa ultPrinter(stri ng employeeFullNam e)
calls EmployeeInfo GetEmployeeInfo (employeeFullNa me)
calls ComputerInfo GetEmployeeComp uterInfo(Employ eeInfo info)
returns ComputerInfo.De faultPrinter

<snip>
Point is, if the call to GetEmployeeComp uterInfo fails, there is
no clean way to return that error back from GetEmployeeDefa ultPrinter() or
if the call to GetEmployeeInfo () fails, same thing. I can return null all
the back down the stack, but short of looking at the log (assuming I'm
logging) there is no clean way to determine where the problem was.
This is an exercise in your ability to "see" methods from the outside
rather than from the inside. In effect, you apply the logic from point
#1 over and over again at each level of the call hierarchy. Using your
example:

If GetEmployeeInfo fails (there is no employee with that name), what
does that mean from the perspective of the code that calls
GetEmployheeDef aultPrinter? Is it a normal situation? Or perhaps it's
fatal because the caller should have validated the employee name first?
If it's a normal situation (the caller isn't expected to validate the
employee name) then does the caller need to distinguish between the
employee name being invalid and the employee having no printer? If so,
why wouldn't we force the caller to check the employee name first,
given that it cares about why the employee name doesn't correspond to a
printer? In other words, what's the difference between this:

EmployeeInfo ei = GetEmployeeInfo (employeeFullNa me);
if (ei != null)
{
PrinterInfo pi = ei.DefaultPrint er;
}

and this:

try
{
pi = GetEmployeeDefa ultPrinter(empl oyeeFullName);
}
catch (InvalidEmploye eNameException ien)
{
... handle error ...
}

They're the same amount of code, but the first one doesn't require
exceptions.

In general, if your caller has to distinguish between different error
cases, then it might as well be doing the checking up front, anyway.

One exception might be if your caller has to display error messages to
the user. In these cases I usually do this:

PrinterInfo GetEmployeeDefa ultPrinter(stri ng employeeFullNam e, out
string message);

If GetEmployeeDefa ultPrinter returns null then "message" contains an
error message to display to the user. If you care about the reason for
the error in some cases but not in others, you can always provide an
overload:

PrinterInfo GetEmployeeDefa ultPrinter(stri ng employeeFullNam e)
{
string message;
return GetEmployeeDefa ultPrinter(empl oyeeFullName, out message);
}
3) How do you decide what exceptions to catch and which ones not to?
I can't remember all of the lists I've posted on this topic, but here
are some ideas. Catch an exception if:

1. You can take some logical, alternative action: If the user has no
default printer then you can abort the print job. Note that this is
different from "machine is out of memory" in which case you want to
crash and burn.

2. You want to transform the exception into a different exception. For
example, you may call a method that throws a DivideByZeroExc eption, but
that might be meaningless to your caller, to whom you might want to
throw an ArgumentExcepti on because the DivideByZeroExc eption happened
because the froobitz value was too large.

3. You might want to remember the exception and throw it (or a
different exception) later. For example, if you're processing 1000
items, you might want to remember that there were exceptions and then
throw one exception at the end, rather than bailing at the first error.

4. You want to ignore it, which I suppose is taking logical alternative
action.
I have read that if I know I can handle it(IE: FileNotFound) then I can catch
it and act accordingly, but that would suggest that it's OK to let all
others bubble up... bubble up to where? Application.Run ()? What guidelines
are there?
Take a look at the events AppDomain.Unhan dledException and
Application.Thr eadException.
4) <snipAn example method is:
string GetCustomerFirm warePath(Custom er customer);
This function is similiar to GetEmployeeDefa ultPrinter() in that it makes a
lot of other calls that could result in an error, either acceptable or
fatal. What I have tried to do in my design is avoid having code like this
scattered throughout my Presenters and other task code:
<code>
// Presenter method to get a customer's firmware path and display in the
view
// All manufactured products have a record of what customer they are for
and from that, what firmware should be loaded
ProductInfo productInfo =
_productionServ ice.GetProductR ecordFromSerial Num(serialNumbe r);
if(productInfo == null)
{
// show error
return false;
}

Customer customer = _firmwareServic e.GetCustomerFr omProductInfo(p roductInfo
;
if(customer == null)
{
// show an error
return false;
}

string firmwarePath = _firmwareServic e.GetCustomerFi rmwarePath(cust omer);
if(firmwarePath == null || firmwarePath.Le ngth < 1)
{
// show an error
return false;
}
</code>
The first question you have to ask yourself is whether in each of those
cases the user should see a different error message. If so, and there's
no way to show a generic error (that meets requirements), then I would
go with the "out string message" solution I mentioned above.

Or, the other solution is to force the caller to check things
beforehand, and have the called method specifically state in its header
comments that passing invalid information results in an exception.
(I.e. it's fatal, because the caller should have checked the arguments
before making the call.) This isn't as bad as it sounds, because the
caller cares about the different error cases anyway, and has to check
either before or after, anyway.

Often, however, the answer is that "The user doesn't care why it
failed, only that it failed," in which case it's enough to simply
return "false" and report a generic failure.

Jul 7 '06 #4
Excellent reply, Bruce, thank you for taking the time!
I've got V's and yours printed out. These are exactly the kind of responses
I was hoping for.

"The way to decide is to ask yourself whether not finding a customer for
that serial number is something that should "never happen", or
something that is a common possibility. "
This part is great advice. There are operations in my application that
should never have null values. A situation like "If you are here in this
function, then the customer BETTER exists, otherwise there is another
problem somewhere else"

So in those cases throwing an exception would be a good decision.

OK, thanks again for the response!
"Bruce Wood" <br*******@cana da.comwrote in message
news:11******** *************@b 28g2000cwb.goog legroups.com...
Steve wrote:
>1) string GetCustomerFirm warePath(string serialNumber) - <snip>
In the event that a customer can't be
located from the serialNumber parameter, is it a better choice to return
null and check for it or to throw an exception from
GetCustomerFir mwarePath()? Possibly even my own exception, IE:
"CustomerNotFo undException"? I have read that exceptions shouldn't be
used
for logic, but I have been spending a lot of time with the Patterns and
Practices group's Composite Application Block and in one of the examples,
they use exceptions in this manner.

This very much depends upon context, and so looking at the method in
isolation, there's no right answer. Since you have the luxury of both
writing the method and writing its caller, you may be able to make a
definitive choice.

The way to decide is to ask yourself whether not finding a customer for
that serial number is something that should "never happen", or
something that is a common possibility. If it's the former, then an
exception is an appropriate choice; if it's the latter then you should
do one of two things:

1. Return null, but this works only if there's only one error
condition, or there are multiple error conditions but you don't need to
distinguish between them, so there's only one error condition at the
level of GetCustomerFirm warePath, conceptually speaking, or

2. Provide another method that will check for the error condition, and
then make GetCustomerFirm warePath fail with an exception. So, you might
right CustomerHasFirm warePath, which returns true or false, and then
GetCustomerFirm warePath will die with an exception if there is no
customer, because the caller should have checked first. See the
Framework's TryParse / Parse methods to see this in action.
>2) methodA calls MethodB which calls MethodC, MethodD and MethodE. IE:
PrinterInfo GetEmployeeDefa ultPrinter(stri ng employeeFullNam e)
calls EmployeeInfo GetEmployeeInfo (employeeFullNa me)
calls ComputerInfo GetEmployeeComp uterInfo(Employ eeInfo info)
returns ComputerInfo.De faultPrinter

<snip>
Point is, if the call to GetEmployeeComp uterInfo fails, there is
no clean way to return that error back from GetEmployeeDefa ultPrinter()
or
if the call to GetEmployeeInfo () fails, same thing. I can return null
all
the back down the stack, but short of looking at the log (assuming I'm
logging) there is no clean way to determine where the problem was.

This is an exercise in your ability to "see" methods from the outside
rather than from the inside. In effect, you apply the logic from point
#1 over and over again at each level of the call hierarchy. Using your
example:

If GetEmployeeInfo fails (there is no employee with that name), what
does that mean from the perspective of the code that calls
GetEmployheeDef aultPrinter? Is it a normal situation? Or perhaps it's
fatal because the caller should have validated the employee name first?
If it's a normal situation (the caller isn't expected to validate the
employee name) then does the caller need to distinguish between the
employee name being invalid and the employee having no printer? If so,
why wouldn't we force the caller to check the employee name first,
given that it cares about why the employee name doesn't correspond to a
printer? In other words, what's the difference between this:

EmployeeInfo ei = GetEmployeeInfo (employeeFullNa me);
if (ei != null)
{
PrinterInfo pi = ei.DefaultPrint er;
}

and this:

try
{
pi = GetEmployeeDefa ultPrinter(empl oyeeFullName);
}
catch (InvalidEmploye eNameException ien)
{
... handle error ...
}

They're the same amount of code, but the first one doesn't require
exceptions.

In general, if your caller has to distinguish between different error
cases, then it might as well be doing the checking up front, anyway.

One exception might be if your caller has to display error messages to
the user. In these cases I usually do this:

PrinterInfo GetEmployeeDefa ultPrinter(stri ng employeeFullNam e, out
string message);

If GetEmployeeDefa ultPrinter returns null then "message" contains an
error message to display to the user. If you care about the reason for
the error in some cases but not in others, you can always provide an
overload:

PrinterInfo GetEmployeeDefa ultPrinter(stri ng employeeFullNam e)
{
string message;
return GetEmployeeDefa ultPrinter(empl oyeeFullName, out message);
}
>3) How do you decide what exceptions to catch and which ones not to?

I can't remember all of the lists I've posted on this topic, but here
are some ideas. Catch an exception if:

1. You can take some logical, alternative action: If the user has no
default printer then you can abort the print job. Note that this is
different from "machine is out of memory" in which case you want to
crash and burn.

2. You want to transform the exception into a different exception. For
example, you may call a method that throws a DivideByZeroExc eption, but
that might be meaningless to your caller, to whom you might want to
throw an ArgumentExcepti on because the DivideByZeroExc eption happened
because the froobitz value was too large.

3. You might want to remember the exception and throw it (or a
different exception) later. For example, if you're processing 1000
items, you might want to remember that there were exceptions and then
throw one exception at the end, rather than bailing at the first error.

4. You want to ignore it, which I suppose is taking logical alternative
action.
>I have read that if I know I can handle it(IE: FileNotFound) then I can
catch
it and act accordingly, but that would suggest that it's OK to let all
others bubble up... bubble up to where? Application.Run ()? What
guidelines
are there?

Take a look at the events AppDomain.Unhan dledException and
Application.Thr eadException.
>4) <snipAn example method is:
string GetCustomerFirm warePath(Custom er customer);
This function is similiar to GetEmployeeDefa ultPrinter() in that it makes
a
lot of other calls that could result in an error, either acceptable or
fatal. What I have tried to do in my design is avoid having code like
this
scattered throughout my Presenters and other task code:
<code>
// Presenter method to get a customer's firmware path and display in the
view
// All manufactured products have a record of what customer they are for
and from that, what firmware should be loaded
ProductInfo productInfo =
_productionSer vice.GetProduct RecordFromSeria lNum(serialNumb er);
if(productIn fo == null)
{
// show error
return false;
}

Customer customer =
_firmwareServi ce.GetCustomerF romProductInfo( productInfo
;
if(customer == null)
{
// show an error
return false;
}

string firmwarePath = _firmwareServic e.GetCustomerFi rmwarePath(cust omer);
if(firmwarePat h == null || firmwarePath.Le ngth < 1)
{
// show an error
return false;
}
</code>

The first question you have to ask yourself is whether in each of those
cases the user should see a different error message. If so, and there's
no way to show a generic error (that meets requirements), then I would
go with the "out string message" solution I mentioned above.

Or, the other solution is to force the caller to check things
beforehand, and have the called method specifically state in its header
comments that passing invalid information results in an exception.
(I.e. it's fatal, because the caller should have checked the arguments
before making the call.) This isn't as bad as it sounds, because the
caller cares about the different error cases anyway, and has to check
either before or after, anyway.

Often, however, the answer is that "The user doesn't care why it
failed, only that it failed," in which case it's enough to simply
return "false" and report a generic failure.

Jul 8 '06 #5

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

Similar topics

7
2710
by: Ekim | last post by:
hy, I've a question concerning exception-handling in c++: is there a possibility to catch any exception (I know one can do that by "catch(...)") and display its default-error-message (like in Java)? or do you have to create your own exceptions and make your own error-messages? I would only need the error-number or something like a short description which exception occured, and subsequently I want to write it to a logfile.
3
1921
by: Gonçalo Rodrigues | last post by:
Hi all, I've got two somewhat general questions related to exception handling in C++. My usual programming language is the lovely and flexible Python, but for various reasons, including the need to interface with third-party libraries, get extra performance, etc. I have to use C++. Now in Python, being a dynamically typed language, everything is pushed to the run-time. Additionaly, since the language does not guarantee deterministic...
11
4841
by: suzy | last post by:
i am trying to write aspx login system and the login process requires a validity check of username and password. i have been told that raising exception is costly, but i want a custom error message to be displayed depending on what error occurred (let's say: invalid username, invalid password, password must contain 5 or more characters, etc). at the moment, my login method is returning true/false depending on whether the login was...
9
2234
by: Gustaf | last post by:
I'm confused about structured error handling. The following piece of code is a simplification of a class library I'm working on. It works, and it does what I want, but I'm still not convinced that I have been doing it right. I think I overdo it. Please have a look: -- using System; using System.IO;
16
2552
by: Chuck Cobb | last post by:
I'm implementing a centralized exception handling routine using the Enterprise Library Exception Management Application Block. I trap all unhandled exceptions to one place using the following method: // --- Create an Exception Handler for Thread Exceptions ---------------- Application.ThreadException += new ThreadExceptionEventHandler(OnThreadException);
5
3835
by: Bry | last post by:
I've created a class that offers an enhanced way of handling fatal exceptions. The class allows the user to optionaly submit a http based anonymous error report to myself, and also records details in the application log. The static method is overloaded, and supports passing exceptions and/or strings just like throwing an exception.The class will also fall back to the standard exception handling if something goes wrong in my class. As an...
35
3817
by: jeffc226 | last post by:
I'm interested in an idiom for handling errors in functions without using traditional nested ifs, because I think that can be very awkward and difficult to maintain, when the number of error checks gets about 3 or so. It also gets very awkward in nested loops, where you want to check for normal loop processing in the loop condition, not errors. Yes, you could put some generic exit flag in the loop condition, but when you're simply done if...
7
395
by: =?Utf-8?B?THVib21pcg==?= | last post by:
Hi, Is it possible to set up C# compiler so that I would get a warning when I miss any exception thrown by a framework? Something like in Java, where the compiler forces you to handle all exceptions. Thanks,
37
1926
by: Sweetiecakes | last post by:
Hello I'm a bit confused on how one should handle exceptions. I'm currently building an ADO.NET Windows Forms application. I've built a class for manipulating data within the database in question. This class is used from forms. Let's assume that there is an SQL error: this will throw an exception. Where should I handle it? How should I handle it? What to show when giving an error message? Is there any "centralized" way of handling...
0
9928
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, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9776
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
11100
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
10718
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
10816
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
10402
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
9555
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
7111
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 then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5781
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 last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...

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.