Re: try, finally

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



--- Jason Cipriani <jason.cipriani@xxxxxxxxx> wrote:
> Thanks for the long response, Ted. Although I
> disagree with most of
> it, I appreciate your time. Some of the points you
> have made are
> slightly unclear:
> 
Just a quick note.  I won't answer all, since Eljay
already did so brilliantly.  I am not sure, though,
why he regards our shared approach to exceptions and
error handling as extremely conservative.

> > Your error
> >  condition, then, doesn't arise.
> 
> I am not sure what you mean. If a file does not
> exist and therefore
> can not be opened, notifying the user of the error
> does not cause the
> file to exist.
> 
But the file the program attempts to open may not
exist because the user had a little typo in the file
name or path he entered.  When he types the file name
and path, before you do anything else, it is dirt
simple to check to see if it exists, and if it
doesn't, prompt the user to correct the file name or
path before you attempt to do anything else.  When you
do this, you prevent any predictable error condition
from happening at all.

Look, C++ has a whole suite of error detection and
handling capability.  To use only exceptions is
somewhat like a carpenter having only a hammer trying
to hammer screws into place.  If all you have is a
hammer, everything looks like a nail.  But if you have
a set of screw drivers in your belt along with your
hammer, you'll use the right tool for the job.

> > User error WRT data
> >  input is common enough that it is much better to
> test
> >  for all errors that you can test for, and prompt
> the
> >  user for corrective action than it is to just
> throw
> >  exceptions willy nilly every time a statement
> doesn't
> >  give you what you wanted.
> 
> Agreed. I don't see what is willy nilly.

You're throwing everywhere.  It is almost as if you
have a bad case of cyber-stomache flu.  You are using
exceptions for flow control.  That is not what they're
there for.  Eljay's brilliant description of return
codes (including especially his smart return code
objects) is a much better option.  And don't forget
assertions have a valid role in many cases also.

> In this
> particular example, I
> have an XML file that contains some data that I need
> to load. The XML
> file must adhere to a very specific structure that
> has been defined
> elsewhere. When the user chooses to load the file,
> the file must
> either be 100% compliant with the defined structure,
> or it will fail
> to load. I have no desire to prompt the user with
> message boxes such
> as "Sorry, but the X data element was missing from
> this data file,
> would you mind telling me what you think the value
> should be so I can
> recover and continue?"

I don't have a quarrel with you there.  Doing that may
well be a stupid thing to do.  But you ought to have
an idea as to what the user CAN do to address the
problem.  Or are you content with leaving the user in
a situation where he can't finish his task because
there is a problem with the data file you need to work
with?  Can the file be repaired?  Regenerated?  What
is the user supposed to do when your program dies just
because of a problem with the data file?  But on the
other hand, maybe the message box you reject out of
hand is the right thing to do because maybe the user
can find the missing data somewhere and enter it.  I
can't tell at this stage because I don't know your
data processing stream.

> A user would not be able to
> answer that
> question in my case anyway. Instead, if the file has
> a slight problem
> (it should not, as the files are not
> hand-generated), I want to notify
> the user that the file could not be loaded. Of
> course, I would provide
> them with a reason why the file could not be loaded,
> but it is not
> always necessary, or even possible, to allow the
> user to intervene and
> correct an error condition themselves. Therefore, in
> the XML example,
> if any one of those operations fails, the entire
> load operation
> *should* fail, and therefore every operation
> warrants an error return
> on failure.
Then design an appropriate suite of error code
objects, and return them.

> In this case, exceptions are a great
> error return, because
> they can store a lot more information than, say,
> returning an integer
> from a function. In fact, this is *precisely* what
> exceptions are
> designed for.
> 
Not quite. They do a lot more than return an error.  I
make extensive use of exceptions and exception
handlers, but you will never find a case in my code
where I use them for flow control.  

At this point, you need to step back and look at the
bigger picture.  The person using your program has a
job to do, and your program ought to be making it
easier for him to do it.  If an error condition
arises, what does he do?  Just give up on getting the
job done?  He'd not last long if he told the boss he
couldn't do his job because your program choked on a
file.  His employer would rightly expect that he do
whatever is necessary to fix the problem and carry on.
 It may well be correct that the user wouldn't have
the knowledge or information required to provide the
detailed data expected at some point in your file, but
you say that the file is not generated manually.  As
the designer of your software, you have to determine
what your user can do to get his job done even when
your program detects a problem in the source data
file.  You have to design your data processing stream
to be fail safe, or at least safe fail, so that what
ever happens, the user can do something to recover and
carry on to finish the job.  If you allow your data
processing stream to be designed in a way that it can
happen that an unrecoverable error can occur, then
your data processing stream is too brittle and needs
to be revised so that the user can recover regardless
of what happens.

I know this isn't always easy, but it is necessary. 
Trust me, I have had to develop software for client's
whose users were secondary school graduates with no IT
experience at all.  They would be baffled at seeing
the kinds of error messages you and I would understand
at a glance.  Stepping out of the mind of a programmer
into the mind of your user is probably one of the
hardest things you'll have to learn to do, but it will
pay dividends.  With some kinds of users, the meanest
thing you can do is abruptly terminate with a brief
error message.  

In some of my programs, I had to go the extra mile and
build in some primitive artificial intelligence, to
guide the user through the process of correcting any
one of a number of problems that could be guaranteed
to arise, using their language, not mine.  Yes, there
are things they can not fix immediately themselves.  

My program would monitor, for example, the hardware
that provided data feeds to the program.  It is
certain that such hardware would fail on occasion. 
The user is not in a position to fill in the missing
data, but my program would a) let them know a problem
had arisen, b) walk them through a process of applying
whatever fixes they COULD try, and if the device
itself had developed a fault, direct them to replace
it (so they can continue to work while the defective
unit is repaired), and they don't find themselves in a
position of putting in several days or weeks on a task
without knowing some piece of hardware had failed. 
That kind of waste or inefficiency can be expensive,
and your clients will bless you or curse you depending
on how well you prevent such waste in the use
/operation of expensive equipment and wasted manpower.

While ensuring errors are always handled, and
consideration is given to what calling code needs to
know, is part of the picture, there is much more to
analysis of possible error conditions, and prediction,
detection and handling of them.  Exceptions have a
role, as do return code objects, and assertions.  But
that is really the small picture that needs
consideration in the context of who the clients and
users are, what they know and what they need to do. 
The software is not complete until you can guarantee
that the user can complete all tasks, that involve use
of the software, that have been assigned by the
client, regardless of what happens.

Trust me, I am not trying to be mean or hard on you. 
I am just trying to pass on a few things you won't
find in the text books, or even in those wonderful
reference books by geniuses like Sutter, or Stroustrup
or Josuttis or Meyers or Lippman.  I can't praise the
books by such authors highly enough, but there is much
learned only by serving people, by developing software
for them, for decades.

In my experience, the vast majority of errors can be
predicted, and therefore prevented, and that means
flow control, and that in turn means primarily error
return code objects.

HTH

Ted

[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux