|
Boost : |
From: Peter Dimov (pdimov_at_[hidden])
Date: 2003-01-16 11:16:54
From: "William E. Kempf" <wekempf_at_[hidden]>
>
> Peter Dimov said:
[...]
> >> 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
>
> Who says it's open file?
You did:
> >> Knowing that "no such file or directory" was
> >> thrown by "open_file" doesn't help the end user [...]
> Maybe it came from is_directory() called from
> open_file(). Now you've lost the USEFUL context because we're two levels
> removed from the throw point.
Maybe it did, although I don't see how could open_file throw an
("is_directory", "file_not_found") exception. It is perfectly legal, but low
QoI. Even if open_file calls is_directory (I don't see why), even if it
didn't check exists() first, or it did, but the file/directory disappeared
between exists and is_directory (highly unlikely), I would expect a good
implementation to translate ("is_directory", "file_not_found") to
("open_file", "file_not_found") in this context.
In less contrived examples the need to translate exceptions would be rare.
who() is not the _exact_ function name that has thrown the exception. It
identifies the action that failed, using documented function names as
idetifiers. As a QoI issue, the library will return a who() string that is
the best representation of the action that failed.
In particular, if open_file() calls, under the hood, detail::open_file_impl,
it should _not_ throw exceptions with "detail::open_file_impl" as a who()
string.
> > 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 if both open_file() and copy_file() call is_directory() which throws a
> file_not_found exception... who provides no benefit at all.
Correct. You definitely can produce a broken library implementation where
who() would provide no benefit at all.
> You are
> pre-supposing a lot with who that at least in some cases won't be true
No, I am not pre-supposing anything about who(). It is a very simple
concept. I trust the library to give me an useful who() string. I use the
who() string to produce an user-friendly error message. If the library gives
me a misleading who() string, I will produce a misleading message.
> I understand what purpose you want who() to meet, I just don't think it
> can do so. Nor do I see a great need for it to. IF you plan to recover
> from an exception, you'll do it as close to the throw point as you
> possibly can, where you (not the library) will have enough contextual
> information to provide a meaningful error message to the user, and who()
> doesn't make much difference here. If you don't plan to recover, then the
> information needed is more for the developer to diagnose the problem than
> for the end user's benefit, and in that case who() is certainly not
> useful.
Using an undefined "recover" verb is typical for such discussions. :-)
No, I don't want to recover. I want to inform the user what happened.
> > 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.
>
> Ahh... that debate wages on. I've got two comments about it. First, not
> everyone agrees with this rigid definition, as is evidenced by the
> numerous langauges in which an exception IS used for general errors and
> even by the names given to many of the C++ standard exception types.
A rigid definition? God forbid. This is only a guideline.
Q: When should I use an exception?
A: Nobody knows, but a good policy is to watch your clients. If they spend
most of their time writing try blocks around calls to your function,
consider using a return value instead.
There is no general answer, and the guideline most definitely doesn't
equal...
> Second, even with a strict usage policy of "only for
> unexpected/exceptional conditions",
... "Exceptions are for exceptional situations only", which I disagree with.
> if you plan to recover you need to do
> it as close to the throw point as possible, and if you don't plan to
> recover the end user hardly needs to be informed of something like "Could
> not open file 'foo.txt'." Generally his response would be "So, why did
> the application crash because of that?"
The application didn't crash. The user tried to do something. The attempt
failed. "Recovery" is meaningless. It is polite to inform the user why his
actions did not produce the expected result. Why do you equate a
filesystem_error being thrown with a crash?
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk