Boost logo

Boost :

Subject: Re: [boost] program options (consider using BOOST_THROW_EXCEPTION)
From: Leo Goodstadt (leo.goodstadt_at_[hidden])
Date: 2012-06-27 07:46:01


> On 22 June 2012 17:51, Vladimir Prus <ghost_at_[hidden]> wrote:
>
> > On 22.06.2012 11:33, Emil Dotchevski wrote:
> >
> >> On Thu, Jun 21, 2012 at 11:44 PM, Vladimir Prus<ghost_at_[hidden]>  wrote:
> >>
> >>  On 20.06.2012 07:44, Rowan James wrote:
> >>>
> >>>  On a related note; is there interest in a patch set to use
> >>>> BOOST_THROW_EXCEPTION to add this (yes, programmer-oriented) information
> >>>> to
> >>>> the exceptions thrown by Program Options and/or other Boost libraries?
> >>>>
> >>>>
> >>> Sorry, but I kinda miss context here (and I did read your original post).
> >>> What are advantages of
> >>> using BOOST_THROW_EXCEPTION and what are drawbacks? Could you summarize
> >>> those for me?
> >>>
> >>>
> >> Allow me :-
> >>
> >> BOOST_THROW_EXCEPTION, being a macro, is able to record the file name, the
> >> function name, and the line number of the throw, which is useful when
> >> diagnosing unexpected exceptions:
> >>
> >> catch(...)
> >> {
> >>   std::cerr<<  "Unexpected exception caught. Diagnostic information
> >> follows.\n";
> >>   std::cerr<<  boost::current_exception_**diagnostic_information();
> >> }
> >>
> >> The exception object is examined dynamically for any and all useful
> >> information: type, what(), throw location, any stored boost::error_info
> >> objects, etc. The location of the throw (if available) is formatted in a
> >> way Visual Studio understands: double-clicking shows the throw location,
> >> similarly to double-clicking compile errors.
> >>
> >> The downside is that when templates are involved, BOOST_CURRENT_FUNCTION
> >> (invoked by BOOST_THROW_EXCEPTION) can bloat the code. There is a Trac
> >> ticket for this.
> >>
> >
> > Emil,
> >
> > thanks for explaining. Given the above, I am not sure I am interested in
> > using
> > BOOST_THROW_EXCEPTION for program_options, given that exceptions are used
> > there to report
> > user mistakes mostly, and so function name or file line is of limited
> > interest.
> >
> > Thanks,
> > Volodya
>
>
> Thanks Emil.
>
> If I can make the case in favour of BOOST_THROW_EXCEPTION, it is for the
> very reason that they are reporting user mistakes.  The throw location for
> an exception is typically accompanied by, or at least close to, the logic
> that delineates such a user mistake from acceptable input.  As such, it is
> a useful remedy in itself; but also gives the user specific information for
> finding documentation relevant to fixing the error.  Without it, we have at
> best the entry point into the library that; and often a lot less if the
> exceptions are caught at a higher level.
>
> Documentation for valid inputs or states to a function can only say so much
> about all the possible errors or exceptions that may occur.

To elaborate on what Volodya said, program_options is unusual (for
Boost) library in its use of exceptions:

Most of the time, exceptions are there to inform the programmer of an
error in the programme.

However, the majority of exceptions in program_options are there to
indicate a problem in the construction of the command line by the
*end-user* (not the programmer).
In other words, the program *is* working exactly as designed. The
programmer has no interest in the provenance of these exceptions
*except* that they can be used to inform the end-user how they should
retype the command line and try again.

So, for example, ten times a day, I will type something like
   ls --colour *
and ls will tell me
  ls: unrecognized option '--colour'
and I will know to retype the US spelling...
  ls --color *

If "ls" were using program options, an unrecognised option exception
message will be thrown which eventually allows this informative
message to be displayed before exiting.

It is entirely unhelpful for the end-user to have
Exception XXX on line xxx of file yyy....

To make it easier to use program options *in English*, the exception
messages have been recently rewritten to be maximally informative to
the end-user rather than the programmers. Thus we can take e.what()
and write it out to std::cerr without further ado.
Of course, for localisation, these error messages have to be
reconstructed in the appropriate language. Hopefully, there is enough
data in each exception to allow this.

Curiously, the current design of exceptions in program_options ended
up try to mirror what Emil has done in BOOST_THROW_EXCEPTION. When the
exception is thrown deep in the bowels of the command line parsing, it
does not have the full context which would allow an informative
message to be constructed.
The exception has to be propagated up, and then "decorated" before
being rethrown.

The alternative was to pass the full context down the function call
hierarchy to each point at which exceptions can be thrown. This made
the code horribly convoluted and ugly, and provoked loud cries of
anguish from Volodya.

Leo


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