Boost logo

Boost :

From: William E. Kempf (wekempf_at_[hidden])
Date: 2003-01-17 01:56:58


Peter Dimov said:
> 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 [...]

Apples to oranges. I was presenting seperate example cases. Both are
valid, both illustrate the problem with who(), just at different levels.

>> 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.

But if every level of the call stack does such a translation, there's no
need for who() to begin with. open_file() knows it was thrown by
is_directory(), because it called is_directory(). change_config() knows
it was thrown by open_file(), because it called open_file(). And on up
the call stack.

> 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.

I.e. you advocate who() only relying upon the implementation to change the
value as it moves up the call stack (whether that be a conceptual call
stack or a physical program call stack matters little here). As long as
you're doing that... I see nothing that who() provides that's not already
present in the program context, as I pointed out above.

>> > 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.

And the only way to not produce a broken library implementation results in
providing no context that's not available to the programmer to begin with.

>> 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.

Recovery still takes place here.

>> 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?

Recovery is hardly meaningless in this case. The recovery consisted of
informing the user of his mistake, and probably asking him to try again.
That's certainly "recovery", and is hardly "meaningless".

William E. Kempf
wekempf_at_[hidden]


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