Boost logo

Boost :

From: Ben Artin (macdev_at_[hidden])
Date: 2006-09-02 06:30:42


In article <20060824085903.GF9119_at_[hidden]>, Gerhard Wesp <gwesp_at_[hidden]>
wrote:

> On Wed, Aug 23, 2006 at 11:20:20AM -0700, Emil Dotchevski wrote:
> > If I understand you correctly, you are storing a user message in the
> > exception when you throw it, and then use std::exception::what() to
> > retrieve
> > it, right? This approach is problematic for several reasons, most notably
>
> Indeed. I don't localize error messages, in fact I've never met a
> program that correctly and completely implemented localized error
> messages. I guess it's because the problem doesn't scale so well.

It doesn't really matter if a program correctly and completely implements
localized error messages -- even if you only get the most common error messages
translated into the most languages most commonly used among your users, you will
make a huge difference in their ability to understand what your program is
trying to tell them. Inability to solve the entire problem is not an excuse to
try solving important parts of it.

The problem of localizing error messages is not fundamentally harder than
producing useful error messages in English. If you can do English well (and I do
not consider "Parsing data file: couldn't open <filename>: <error>" to be a good
error message in English), you probably have enough machinery in the code to do
most other languages well, and localization becomes a simple matter of hiring
translators.

For example, the app that I work on will give you error messages such as "The
file 'XYZZY' could not be transferred because you do not have the required
permissions on the server." -- and that still leaves a lot of room for
improvement. Importantly, though, once we built the ability to construct
meaningful English sentences using information from high levels of the app
(where the user action is know) and low levels of the app (where the precise
failure is known), also doing so in the six other languages that we support was
trivial.

> > because the user message has to be localized, but also because different
> > programs may need to output different messages in response to the same
> > exception thrown by a shared library.
>
> Hmmm... Can you give an example? I try to restrict the what() string
> to be indepentent of library usage and add more information higher up
> the call stack, possibly re-throwing afterwards. E.g., a file object
> constructor might throw "couldn't open <filename>: <error>" and then,
> it's caller might prepend some more context information to make that
> either
> "Reading configuration file: couldn't open <filename>: <error>"
> or
> "Parsing data file: couldn't open <filename>: <error>"
>
> This works quite well, but yeah, maybe there are situations where string
> concatenation is too simplistic.

Any time you attempt to address your users in a language that they use in
everyday life, as opposed to the geek language that makes the programmers' lives
easier, string concatenation is way too simplistic.

Error information returned by a well-designed API carries enough semantic
content for the clients of that API to use in their own representation of the
errors -- different clients have different error reporting needs. As a result,
there is nothing inherently wrong with using strings for identifying errors, as
long as the exact values of those strings are documented as part of the API, and
are maintained as any other part of the API (e.g., if you want to change one of
them, you have to consider backward compatibility). Basically, if an API treats
error strings returned as it would treat error codes returned, then there is no
problem; on the other hand, if an API treats error strings as private values
that clients cannot rely on, then the clients have their hands tied.

(As an aside, part of what makes user-friendly error reporting difficult is the
fact that many APIs have poorly defined error semantics in the first place.)

Ben

-- 
I changed my name: <http://periodic-kingdom.org/People/NameChange.php>

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