473,835 Members | 1,777 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Confused about error handling

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;

namespace ErrorHandlingTe st
{
class ErrorHandlingTe st
{
[STAThread]
static void Main(string[] args)
{
try
{
Wrapper w = new Wrapper(args[0], args[1]);
}
catch (System.Excepti on e)
{
Console.WriteLi ne(e.Message);
}
}
}

class Wrapper
{
public Wrapper(string file1, string file2)
{
try
{
ReaderType1 reader1 = new ReaderType1(fil e1);
ReaderType2 reader2 = new ReaderType2(fil e2);
}
catch (System.Excepti on e)
{
throw new System.Exceptio n(e.Message);
}
}
}

class ReaderType1
{
public ReaderType1(str ing file)
{
try
{
StreamReader sr = new StreamReader(fi le);
}
catch (System.IO.File NotFoundExcepti on e1)
{
throw new System.IO.FileN otFoundExceptio n(e1.Message);
}
catch (System.IO.Dire ctoryNotFoundEx ception e2)
{
throw new System.IO.Direc toryNotFoundExc eption(e2.Messa ge);
}
}
}

class ReaderType2
{
public ReaderType2(str ing file)
{
try
{
StreamReader sr = new StreamReader(fi le);
}
catch (System.IO.File NotFoundExcepti on e1)
{
throw new System.IO.FileN otFoundExceptio n(e1.Message);
}
catch (System.IO.Dire ctoryNotFoundEx ception e2)
{
throw new System.IO.Direc toryNotFoundExc eption(e2.Messa ge);
}
}
}
}

--

The part that makes up the class library is the Wrapper and reader
classes. These classes have no direct contact with the user interface,
but there are plenty of things that can go wrong inside them.

After writing and running this, I found that I could remove all error
handling except in Main() and the program ran just as fine (it could
still separate between not finding the folder and not finding the file).
It makes me wonder why I have to write several catch blocks, when all I
need is to catch System.Exceptio n when I use my class library (like in
Main() above).

I want to write robust code, but I fail to see how the code gets *more*
robust by adding error handling inside the class library. It appears as
if classes that shouldn't talk with the user doesn't need error
handling! There must be something I'm missing here.

Gustaf
Nov 21 '05 #1
9 2232
Gustaf wrote:
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;

namespace ErrorHandlingTe st
{
class ErrorHandlingTe st
{
[STAThread]
static void Main(string[] args)
{
try
{
Wrapper w = new Wrapper(args[0], args[1]);
}
catch (System.Excepti on e)
{
Console.WriteLi ne(e.Message);
}
}
}

class Wrapper
{
public Wrapper(string file1, string file2)
{
try
{
ReaderType1 reader1 = new ReaderType1(fil e1);
ReaderType2 reader2 = new ReaderType2(fil e2);
}
catch (System.Excepti on e)
{
throw new System.Exceptio n(e.Message);
}
}
}

class ReaderType1
{
public ReaderType1(str ing file)
{
try
{
StreamReader sr = new StreamReader(fi le);
}
catch (System.IO.File NotFoundExcepti on e1)
{
throw new System.IO.FileN otFoundExceptio n(e1.Message);
}
catch (System.IO.Dire ctoryNotFoundEx ception e2)
{
throw new System.IO.Direc toryNotFoundExc eption(e2.Messa ge);
}
}
}

class ReaderType2
{
public ReaderType2(str ing file)
{
try
{
StreamReader sr = new StreamReader(fi le);
}
catch (System.IO.File NotFoundExcepti on e1)
{
throw new System.IO.FileN otFoundExceptio n(e1.Message);
}
catch (System.IO.Dire ctoryNotFoundEx ception e2)
{
throw new System.IO.Direc toryNotFoundExc eption(e2.Messa ge);
}
}
}
}

--

The part that makes up the class library is the Wrapper and reader
classes. These classes have no direct contact with the user interface,
but there are plenty of things that can go wrong inside them.

After writing and running this, I found that I could remove all error
handling except in Main() and the program ran just as fine (it could
still separate between not finding the folder and not finding the file).
It makes me wonder why I have to write several catch blocks, when all I
need is to catch System.Exceptio n when I use my class library (like in
Main() above).

I want to write robust code, but I fail to see how the code gets *more*
robust by adding error handling inside the class library. It appears as
if classes that shouldn't talk with the user doesn't need error
handling! There must be something I'm missing here.

Gustaf


Your error handling in Wrapper, ReaderType1 and ReaderType2 makes no
sense. You are not doing anything when you catch the exception, you are
not adding any additional information to the exception, you are simply
wrapping the caught exception in another exception of the same type and
throwing that new exception. I would remove all of the exception
handling in those classes in this example as they provide nothing to the
overall value or robustness of the code.

My basic principle on exception handling is only catch exceptions when
you can truly do something intelligent about the exception (note that
these situations are rare in typical programs). Other than that, only
catch exceptions and rethrow exceptions if you plan on adding truly
useful information to the exception that is thrown that will help you
resolve the issue that is causing the exception to be thrown.
--
Tom Porterfield
Nov 21 '05 #2
No, you're on the right track.

The code _doesn't_ get "more robust" as you add more error handling. It
gets "more robust" only when there is a specific exception that you
know what to do with it at a certain point in the code.

In your ReaderType2 and ReaderType1 classes, there's no need to catch
the exceptions you're catching, unless those classes want to:

1. Take some remedial action as a result of the exception.
2. Transform the exception into a different kind of exception because
the new exception would make sense to the caller (context).
3. Add more information to an exception.
4. Don't really care about the exception and can continue anyway
(swallow the exception).
5. Want to defer the exception to a later moment in time.

Other than that, you want to catch all other exceptions at the top
level, but not using the mechanism you're using in Main(). Because of
the structure of Windows applications, a top-level try...catch doesn't
always work.

Look at the AppDomain.Unhan dledException and
Application.Thr eadException events for how to build global exception
handlers for logging, etc.

Nov 21 '05 #3
You have overdo it. In fact, you've made things worse!

public Wrapper(string file1, string file2)
{
try
{
ReaderType1 reader1 = new ReaderType1(fil e1);
ReaderType2 reader2 = new ReaderType2(fil e2);
}
catch (System.Excepti on e)
{
throw new System.Exceptio n(e.Message);
}
}
}

All this is accomplishing is destroying information that was in the original
Exception (like the line number of the throw that originally cause it).
Had you written it as:
public Wrapper(string file1, string file2)
{
try
{
ReaderType1 reader1 = new ReaderType1(fil e1);
ReaderType2 reader2 = new ReaderType2(fil e2);
}
catch (System.Excepti on e)
{
throw;
}
}
}

It would be preserved the original information, making this version merely
pointless, but no harmful.

Basically, you ONLY put a try/catch at the level where you can handle the
error. Exceptions will automatically "bubble up" until it finds a catch.
Since the only thing you ever do with an exception is print the message and
exist your app, you can do that at the top level.

--
Truth,
James Curran
[erstwhile VC++ MVP]

Home: www.noveltheory.com Work: www.njtheater.com
Blog: www.honestillusion.com Day Job: www.partsearch.com
"Gustaf" <gu*****@algone t.se> wrote in message
news:uj******** *****@TK2MSFTNG P15.phx.gbl...
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;

namespace ErrorHandlingTe st
{
class ErrorHandlingTe st
{
[STAThread]
static void Main(string[] args)
{
try
{
Wrapper w = new Wrapper(args[0], args[1]);
}
catch (System.Excepti on e)
{
Console.WriteLi ne(e.Message);
}
}
}

class Wrapper
{
public Wrapper(string file1, string file2)
{
try
{
ReaderType1 reader1 = new ReaderType1(fil e1);
ReaderType2 reader2 = new ReaderType2(fil e2);
}
catch (System.Excepti on e)
{
throw new System.Exceptio n(e.Message);
}
}
}

class ReaderType1
{
public ReaderType1(str ing file)
{
try
{
StreamReader sr = new StreamReader(fi le);
}
catch (System.IO.File NotFoundExcepti on e1)
{
throw new System.IO.FileN otFoundExceptio n(e1.Message);
}
catch (System.IO.Dire ctoryNotFoundEx ception e2)
{
throw new System.IO.Direc toryNotFoundExc eption(e2.Messa ge); }
}
}

class ReaderType2
{
public ReaderType2(str ing file)
{
try
{
StreamReader sr = new StreamReader(fi le);
}
catch (System.IO.File NotFoundExcepti on e1)
{
throw new System.IO.FileN otFoundExceptio n(e1.Message);
}
catch (System.IO.Dire ctoryNotFoundEx ception e2)
{
throw new System.IO.Direc toryNotFoundExc eption(e2.Messa ge); }
}
}
}

--

The part that makes up the class library is the Wrapper and reader
classes. These classes have no direct contact with the user interface,
but there are plenty of things that can go wrong inside them.

After writing and running this, I found that I could remove all error
handling except in Main() and the program ran just as fine (it could
still separate between not finding the folder and not finding the file).
It makes me wonder why I have to write several catch blocks, when all I
need is to catch System.Exceptio n when I use my class library (like in
Main() above).

I want to write robust code, but I fail to see how the code gets *more*
robust by adding error handling inside the class library. It appears as
if classes that shouldn't talk with the user doesn't need error
handling! There must be something I'm missing here.

Gustaf

Nov 21 '05 #4
Besides the good stuff that Tom et al added, in general,
you should only throw exceptions when a condition outside of your code's
assumptions occurs.

In other words, don't use exceptions as a way to provide your intended
functionality even if something bad happens.

An exception should be generated if a real, legitimate unexpected condition
occurs, such as an unavailable database.

You can design your classes so that an exception is not thrown in normal use.

For example, the FileStream class exposes a way of determining whether the
end of the file has been reached.
This avoids the exception that is thrown if you read past the end of the
file.

The following short example shows how to read to the end of the file.

class FileRead {
void Open() {
FileStream stream = File.Open("myfi le.txt", FileMode.Open);
byte b;

// ReadByte returns -1 at EOF.
while ((b == stream.ReadByte ()) != true) {
// Do something here. No Exceptions will be thrown.
}
}
}

As Tom mentioned, its important not only to code defensively with exceptions
that really serve a purpose, but also to decide what the caller will do when
an exception is propagated up the stack.
Peter

--
Co-founder, Eggheadcafe.com developer portal:
http://www.eggheadcafe.com
UnBlog:
http://petesbloggerama.blogspot.com


"Gustaf" wrote:
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;

namespace ErrorHandlingTe st
{
class ErrorHandlingTe st
{
[STAThread]
static void Main(string[] args)
{
try
{
Wrapper w = new Wrapper(args[0], args[1]);
}
catch (System.Excepti on e)
{
Console.WriteLi ne(e.Message);
}
}
}

class Wrapper
{
public Wrapper(string file1, string file2)
{
try
{
ReaderType1 reader1 = new ReaderType1(fil e1);
ReaderType2 reader2 = new ReaderType2(fil e2);
}
catch (System.Excepti on e)
{
throw new System.Exceptio n(e.Message);
}
}
}

class ReaderType1
{
public ReaderType1(str ing file)
{
try
{
StreamReader sr = new StreamReader(fi le);
}
catch (System.IO.File NotFoundExcepti on e1)
{
throw new System.IO.FileN otFoundExceptio n(e1.Message);
}
catch (System.IO.Dire ctoryNotFoundEx ception e2)
{
throw new System.IO.Direc toryNotFoundExc eption(e2.Messa ge);
}
}
}

class ReaderType2
{
public ReaderType2(str ing file)
{
try
{
StreamReader sr = new StreamReader(fi le);
}
catch (System.IO.File NotFoundExcepti on e1)
{
throw new System.IO.FileN otFoundExceptio n(e1.Message);
}
catch (System.IO.Dire ctoryNotFoundEx ception e2)
{
throw new System.IO.Direc toryNotFoundExc eption(e2.Messa ge);
}
}
}
}

--

The part that makes up the class library is the Wrapper and reader
classes. These classes have no direct contact with the user interface,
but there are plenty of things that can go wrong inside them.

After writing and running this, I found that I could remove all error
handling except in Main() and the program ran just as fine (it could
still separate between not finding the folder and not finding the file).
It makes me wonder why I have to write several catch blocks, when all I
need is to catch System.Exceptio n when I use my class library (like in
Main() above).

I want to write robust code, but I fail to see how the code gets *more*
robust by adding error handling inside the class library. It appears as
if classes that shouldn't talk with the user doesn't need error
handling! There must be something I'm missing here.

Gustaf

Nov 21 '05 #5
Good advice, but if I may make one picky correction, don't write code
like this:

while ((b == stream.ReadByte ()) != true)

you should instead write this:

while (b != stream.ReadByte ())

Nov 21 '05 #6
Gustof...Lookin g at your code you seem to be concerned about exceptions
in the constructor, a special situation. Since a constructor does not
return a value, one way to signal a failure of construction is to throw
an exception. So you can let the exception bubble up or you can create
your own custom construction exception and throw that.

The alternative in a nothrow framework would be to catch all exceptions
and if fatal, set a flag in the object noting the object isValid ==
false. This requires methods to check the flag and do innocuous things
if the object state is invalid.

If you are allocating any unmanaged resources in the constructor, your
constructor code should be "transactional, " the code should complete to
success or release any unmanaged resources in try catch and then throw.

Regards,
Jeff

*** Sent via Developersdex http://www.developersdex.com ***
Nov 21 '05 #7
Oh, rats. I wasn't paying attention. My correction should have read:

while ((b == stream.ReadByte ()) != true)

you should instead write this:

while ((b = stream.ReadByte () >= 0)

Or something like that, no? In any event, the original code didn't make
sense.

Nov 21 '05 #8
Bruce Wood <br*******@cana da.com> wrote:
Good advice, but if I may make one picky correction, don't write code
like this:

while ((b == stream.ReadByte ()) != true)

you should instead write this:

while (b != stream.ReadByte ())


In fact, you should almost always actually read a buffer at a time -
and when the call to Read returns 0, that means you've read to the end
of the stream. The differences in efficiency can be really important
there (and you probably know I'm very much against premature
optimisation normally).

--
Jon Skeet - <sk***@pobox.co m>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Nov 21 '05 #9
Many thanks for all the help here. I was learning a lot reading your
answers.

Gustaf
Nov 23 '05 #10

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

Similar topics

2
3277
by: WSeeger | last post by:
When creating a new class, is it encouraged to always include error handling routines within your LET and GET procedures? It's seems that most text books never seem to include much about error handling within classes. Just hoping to hear some programmer's thoughts on error handling.
6
8475
by: Squirrel | last post by:
I have a command button on a subform to delete a record. The only statement in the subroutine is: DoCmd.RunCommand acCmdDeleteRecord The subform's recordsource is "select * from tblVisit order by VisitDt" I'm getting this error message: Errno is 2465. Err.description is "Can't find field '|' referred to in your expression"
13
4494
by: Thelma Lubkin | last post by:
I use code extensively; I probably overuse it. But I've been using error trapping very sparingly, and now I've been trapped by that. A form that works for me on the system I'm using, apparently runs into problems on the system where it will actually be used, and since I used so little error-trapping it dies very ungracefully. I will of course try to fix whatever is causing the error and add error-trapping to the functions where the...
21
4433
by: Anthony England | last post by:
Everyone knows that global variables get re-set in an mdb when an un-handled error is encountered, but it seems that this also happens when the variable is defined as private at form-level. So if "global variables get re-set" doesn't tell the whole story, then what does? ***please note*** I'm not looking for a solution - I'm looking for a more detailed description of what happens when an un-handled error occurs - possibly with help file...
3
2864
by: Stefan Johansson | last post by:
Hi all I'am moving from Visual Foxpro and have a question regarding "best practice" error handling in vb .net. In VFP I have always used a "central" error handling object in order to have a easy and reusable way of handling all errors in a program. The VB 6 coding examples I have seen there has always been error handling code in each program module.
4
1942
by: Al Williams | last post by:
Hi, I have error handling in place throughout my application. I also start the application wrapped in error handling code to catch any unexpected exceptions (i.e. exceptions that occur where I haven't placed error handling code). When I run my app from the IDE, the unhandled errors are caught by the error handling code in my Sub Main routine and the error details are logged to a text file and optionally e-mailed to me for follow-up.
10
2301
by: Anthony England | last post by:
(sorry for the likely repost, but it is still not showing on my news server and after that much typing, I don't want to lose it) I am considering general error handling routines and have written a sample function to look up an ID in a table. The function returns True if it can find the ID and create a recordset based on that ID, otherwise it returns false. **I am not looking for comments on the usefulness of this function - it is
0
11610
by: Lysander | last post by:
Thought I would give something back with a few articles. This article is a bit of code to add error handling. When I have time, I want to write articles on multilingual databases, and Access Security, but I'll start with something short and simple This code was written in Access 2003 but should be valid in Access 2000 By default, when you start a new module, either in a form or report, or a global module, Access does not declare Option...
9
3303
by: MrDeej | last post by:
Hello guys! We have an SQL server which sometimes makes timeouts and connection errors. And we have an function witch writes and updates data in 2 tables on this server. When the SQL server error appears it, in 99%, of the cases, works if we just press the play button in VBA debug. Therefor we have maked an error handling which just tryes again. However, as this error handling is difficult to test because of maybe 1 or 2 errors a day, we...
0
9808
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
9652
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,...
1
10561
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
10235
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
9346
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...
1
7766
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 presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6966
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
5638
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...
1
4434
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

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.