Boost logo

Boost :

From: Peter Dimov (pdimov_at_[hidden])
Date: 2003-01-15 06:20:05


From: "William E. Kempf" <wekempf_at_[hidden]>
> Peter Dimov said:
> >
> > The fact that who() returns a function name is not important; it is not
> > a "mini call stack". A function name is used as a token that identifies
> > the point of failure. What failed? An attempt to open a file? An attempt
> > to read the contents of a directory? An attempt to copy a file? To move
> > a file? You need this information in order to compose a meaninful error
> > message. "No such file or directory" by itself isn't very helpful to the
> > user. What is the name of the file/directory that wasn't found? What did
> > the program try to do with it?
>
> But the "who" is dependent on higher level information than what's
> available to the library.

No, who() is not dependent on higher level information. It only depends on
the location of the throw statement where the exception was created.

Every active exception has one and only one associated throw statement.

To supply who() information, you only need to change

throw E(...);

to

throw E("identifier", ...);

with a suitable predefined "identifier" scheme.

The sequence of events that led to that throw statement being executed, the
execution path, or the call stack might be nice to have, but they aren't
necessarily easy to obtain, and they aren't the information that who() is
intended to provide.

> Knowing that "no such file or directory" was
> thrown by "open_file" doesn't help the end user when the action he took
> was to change a configuration option, for instance.

The end user isn't interested in the function name, which is why who() is
typically not displayed as-is. who() is used as a key into a string table.
In the above situation, where who() is "open_file" and error() is
"boost::filesystem::file_not_found", the user would typically see a message
like

Could not open "foo.txt": No such file or directory

Had who() been "boost::filesystem::copy_file", the message could have been

Could not copy "foo.txt" to "bar": No such file or directory

> And it's no use to
> the programmer to log such information if it's not also logged that the
> user was trying to change the configuration at the time, otherwise there's
> likely several points in the application that could have failed.

That's another subject altogether, the famous logic_error. who() is not
intended to be used as a function name, and runtime errors are something
that does not indicate a bug in the program, they happen in the course of
normal operation.

You can mentally replace

std::string who() const; // function name

with

enum action what() const; // action that failed: open, copy, move, ...

if this will make the above clearer.

> Good error handling will either catch the exception as close to the point
> of error as possible, where there's enough known context to give a
> meaningful report,

Catching exceptions close to the throw point (an exception is not an error)
is typically an indication of bad design. (As is proliferation of try
blocks.) If the client often needs to handle failures locally, the functions
should have been made to report them using a return value.

(This is a very general advice, of course.)

If, on the other hand, you are talking about logic_error exceptions, that
indicate bugs in the program, good error handling will gather the necessary
information at the point where the bug is detected, before the throw (if an
exception is thrown at all.)

> or will log much more information then is available to
> the point of exception generation (at least in a portable manner). I
> can't see how who() is helpful.
>
> > Once you accept that the exception needs to provide an unique token that
> > identifies the point of failure, now the question is how to choose its
> > type and value.
>
> But I don't accept that, unless the FULL point of failure can be
> identified (i.e. a call stack).

How would you use a call stack to generate an user friendly error message?


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk