Pre / post conditions in error handling

D

Dave

Hello all,

I found Herb Sutter's article regarding error handling in the most recent
CUJ to be very, very good. However, in trying to apply what I learned from
the article, I am left with some questions.

I have a function that takes a std::string (that represents a file name) as
a parameter. This function reads in the contents of the file and returns a
struct representing the file's content.

Two things could go wrong inside the function:

1. The function might find that the file does not exist
2. The function might find that the content of the file is invalid

(Some might consider 1 to be a special case of 2.)

The question is: Are these cases a violation of the function's preconditions
or postconditions? According to the error handling philosophy advocated by
Herb in his article, if it is a precondition violation, it should have been
reported as an error in the calling function. Since it wasn't, we should
report a program bug via an assert in the called function. If it is a
postcondition violation, it should be reported as an error in the called
function. Since whether the problem is a precondition or postcondition
problem determines where the error gets reported, it is something I need to
know to properly write my code.

I can reason that these are precondition violations since it seems
justifiable to say that a precondition for the function is that the file
both exist and have valid content.

However, I can also make a reasonable argument that it is a postcondition
violation since the function cannot construct a valid return value. In this
case, the precondition would be nothing more than that the string object
passed in be valid. If it's a valid std::string, the precondition is met,
period.

So, I need a little more guidance than that provided in the article as to
how to classify a problem as a precondition or postcondition violation. I'm
thinking that perhaps it is a subjective thing and that either way you go
could be OK as long as you're consistent. All help will be appreciated!

Thanks,
Dave
 
A

Alf P. Steinbach

* Dave:
I found Herb Sutter's article regarding error handling in the most recent
CUJ to be very, very good.

Haven't read that. Link?

However, in trying to apply what I learned from
the article, I am left with some questions.

I have a function that takes a std::string (that represents a file name) as
a parameter. This function reads in the contents of the file and returns a
struct representing the file's content.

Two things could go wrong inside the function:

1. The function might find that the file does not exist
2. The function might find that the content of the file is invalid

(Some might consider 1 to be a special case of 2.)

The question is: Are these cases a violation of the function's preconditions
or postconditions? According to the error handling philosophy advocated by
Herb in his article, if it is a precondition violation, it should have been
reported as an error in the calling function. Since it wasn't, we should
report a program bug via an assert in the called function. If it is a
postcondition violation, it should be reported as an error in the called
function. Since whether the problem is a precondition or postcondition
problem determines where the error gets reported, it is something I need to
know to properly write my code.

I can reason that these are precondition violations since it seems
justifiable to say that a precondition for the function is that the file
both exist and have valid content.

However, I can also make a reasonable argument that it is a postcondition
violation since the function cannot construct a valid return value.

In this
case, the precondition would be nothing more than that the string object
passed in be valid. If it's a valid std::string, the precondition is met,
period.

So, I need a little more guidance than that provided in the article as to
how to classify a problem as a precondition or postcondition violation. I'm
thinking that perhaps it is a subjective thing and that either way you go
could be OK as long as you're consistent. All help will be appreciated!

It's very easy: don't have condition X as a precondition unless the
caller _can_ ensure that condition X holds (and in that case, if you
choose to have X as precondition then a violation is a logic error).

When you don't have condition X as precondition, but X is needed to
return a useful result: if X can be checked for, then it is a design
issue -- what's most practical -- whether the function should
guarantee the useful result on successful execution, or whether it
should also have X-didn't-hold as a possible normal case result.

A guaranteed useful result means X violation should throw exception.

Otherwise, one way of reporting a possibly "null" result is by using a
wrapper object that either is empty or logically contains the useful
result. The case where the useful result is a simple or small value
type has its own little pattern name, which I forget...
 
D

Dave

Alf P. Steinbach said:
* Dave:

Haven't read that. Link?



It's very easy: don't have condition X as a precondition unless the
caller _can_ ensure that condition X holds (and in that case, if you
choose to have X as precondition then a violation is a logic error).

When you don't have condition X as precondition, but X is needed to
return a useful result: if X can be checked for, then it is a design
issue -- what's most practical -- whether the function should
guarantee the useful result on successful execution, or whether it
should also have X-didn't-hold as a possible normal case result.

A guaranteed useful result means X violation should throw exception.

Otherwise, one way of reporting a possibly "null" result is by using a
wrapper object that either is empty or logically contains the useful
result. The case where the useful result is a simple or small value
type has its own little pattern name, which I forget...

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?

As far as a link goes, there isn't one available at this time as the article
is in print. If anyone else knows of a link I didn't find, please post...
Thanks!
 
S

Siemel Naran

Dave said:
Two things could go wrong inside the function:

1. The function might find that the file does not exist
2. The function might find that the content of the file is invalid

(Some might consider 1 to be a special case of 2.)

The question is: Are these cases a violation of the function's preconditions
or postconditions? According to the error handling philosophy advocated by
Herb in his article, if it is a precondition violation, it should have been
reported as an error in the calling function. Since it wasn't, we should
report a program bug via an assert in the called function. If it is a
postcondition violation, it should be reported as an error in the called
function. Since whether the problem is a precondition or postcondition
problem determines where the error gets reported, it is something I need to
know to properly write my code.

Precondition and postconditions should test constraints between the member
variables of the class, as far as I know. For the two things that could go
wrong, I don't see a straightforward way to fit them into this scheme. So
my design decision is to throw an exception.
These seem to be
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,767
Messages
2,569,572
Members
45,045
Latest member
DRCM

Latest Threads

Top