program options (consider using BOOST_THROW_EXCEPTION)

Hi boost, At version 1.49.0 In testing command line with known unknowns such as -V a location unknown exception is thrown from inside program_options recommending to use BOOST_THROW_EXCEPTION. I've been trying to find this and apply BOOST_THROW_EXCEPTION to eliminate the verbosity for users: ---- Command line incorrect: Throw location unknown (consider using BOOST_THROW_EXCEPTION) Dynamic exception type: boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::program_options::unknown_option>
std::exception::what: unknown option -V ---- With this fixed then it'd be closer to: -------- Command line incorrect: unknown option -V -------- Yet I haven't found where. Baffled. Any hint?

On Tue, Jun 19, 2012 at 6:12 AM, Roger Martin <roger@quantumbioinc.com>wrote:
Hi boost,
At version 1.49.0
In testing command line with known unknowns such as -V a location unknown exception is thrown from inside program_options recommending to use BOOST_THROW_EXCEPTION. I've been trying to find this and apply BOOST_THROW_EXCEPTION to eliminate the verbosity for users: ---- Command line incorrect: Throw location unknown (consider using BOOST_THROW_EXCEPTION) Dynamic exception type: boost::exception_detail::** clone_impl<boost::exception_**detail::error_info_injector<** boost::program_options::**unknown_option> > std::exception::what: unknown option -V
The output you're seeing is generated by boost::diagnostic_information, and that's not a user-friendly but rather a diagnostic message. The suggestion to use BOOST_THROW_EXCEPTION refers to the "Throw location unknown". If BOOST_THROW_EXCEPTION was used by the library, the diagnostic message would have been more complete and include the file/line of the throw. Just catch boost::program_options::unknown_option and display a user-friendly message: catch( boost::program_options::unknown_option & e ) { std::cerr << "Unknown option!"; } catch( ... ) { std::cerr << "Unrecognized exception, diagnostic information follows\n" << boost::current_exception_diagnostic_information(); } Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode

On 20 June 2012 05:55, Emil Dotchevski <emildotchevski@gmail.com> wrote:
On Tue, Jun 19, 2012 at 6:12 AM, Roger Martin <roger@quantumbioinc.com
wrote:
Command line incorrect: Throw location unknown (consider using BOOST_THROW_EXCEPTION) Dynamic exception type: boost::exception_detail::** clone_impl<boost::exception_**detail::error_info_injector<** boost::program_options::**unknown_option> > std::exception::what: unknown option -V
The output you're seeing is generated by boost::diagnostic_information, and that's not a user-friendly but rather a diagnostic message. The suggestion to use BOOST_THROW_EXCEPTION refers to the "Throw location unknown". If BOOST_THROW_EXCEPTION was used by the library, the diagnostic message would have been more complete and include the file/line of the throw.
Or, to use the plain information in the exception; ignore the diagnostic information and just use the what() member of the exception: try { // ... } catch (std::exception& ex) { std::cout << ex.what() << std::endl; } Note that the boost::diagnostic_information() is showing what the result of that is for the exception in the last line: "unknown option -V" Also, be aware that this is not an especially friendly way of doing this; the exception string is never going to be translated for the current locale, is prone to change without notice, etc. etc. Roger is suggesting the Right Way. 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? I'd understand if there is some reason to not using it that I've missed; like minimising dependencies, or no-exception support, for example. However, I use Boost.Exception ( and boost::diagnostic_information() ) extensively, and I often encounter instances where exceptions thrown by Boost libraries themselves lack the information that would be added; Boost.Filesystem and Boost.Format come to mind specifically.

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? Thanks, Volodya

On Thu, Jun 21, 2012 at 11:44 PM, Vladimir Prus <ghost@cs.msu.su> 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 Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode

On 22.06.2012 11:33, Emil Dotchevski wrote:
On Thu, Jun 21, 2012 at 11:44 PM, Vladimir Prus<ghost@cs.msu.su> 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

On 22 June 2012 17:51, Vladimir Prus <ghost@cs.msu.su> wrote:
On 22.06.2012 11:33, Emil Dotchevski wrote:
On Thu, Jun 21, 2012 at 11:44 PM, Vladimir Prus<ghost@cs.msu.su> 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.

Rowan James on 26 June 2012 13:49 wrote :
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.
+1 here I had a case of this with either program_options or property_tree (can't remember which) not that long ago and remember wishing that the library had used boost exceptions rather than some boost:any derived library specific error handling for this very reason. Instead had to step through library code to work out why it had a problem with the particular input. Alex Perry

On 26.06.2012, at 19:03, Alex Perry wrote:
Rowan James on 26 June 2012 13:49 wrote :
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.
+1 here
I had a case of this with either program_options or property_tree (can't remember which) not that long ago and remember wishing that the library had used boost exceptions rather than some boost:any derived library specific error handling for this very reason. Instead had to step through library code to work out why it had a problem with the particular input.
That would be PropertyTree, and I'll put changing that on my todo list. (I do use Boost.Exception, I think, but I'm not attaching information.) Sebastian

Sebastian Redl on 26 June 2012 19:02 wrote :
That would be PropertyTree, and I'll put changing that on my todo list. (I do use Boost.Exception, I think, but I'm not attaching information.)
Sebastian
That would be great thanks! - though my comment was not meant to criticize propertyTree in particular - it's a very useful library - was more trying to use an example to add weight to a general wish that exceptions for boost libraries were more consistent (and including information only available at throw site when applicable) - since this just makes using them even easier given the number of boost libraries that exist now. Alex

On 26.06.2012 21:03, Alex Perry wrote:
Rowan James on 26 June 2012 13:49 wrote :
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.
+1 here
I had a case of this with either program_options or property_tree (can't remember which) not that long ago and remember wishing that the library had used boost exceptions rather than some boost:any derived library specific error handling for this very reason. Instead had to step through library code to work out why it had a problem with the particular input.
What practical value would source location somewhere in any.hpp give you? - Volodya

Vladimir Prus on 27 June 2012 10:41 wrote :
What practical value would source location somewhere in any.hpp give you?
- Volodya
Minor value I admit - but as I think someone mentioned earlier - its very easy to move to this throw site after catching the exception in application code and then can add a breakpoint and rerun. Then can explore the problem in the "correct context" of the code - stepping through all the library code whilst obviously possible can just take a long time - particularly as the code organisation in the library (for sensible reasons) will be more complex than I really want to know about as a user - being able to start at the correct "implementatioin/detail" level with (hopefully) the code which was complaining about the input nearby does help. Alex

On 27 June 2012 22:14, Alex Perry <Alex.Perry@smartlogic.com> wrote:
Vladimir Prus on 27 June 2012 10:41 wrote :
What practical value would source location somewhere in any.hpp give you?
- Volodya
Minor value I admit - but as I think someone mentioned earlier - its very easy to move to this throw site after catching the exception in application code and then can add a breakpoint and rerun.
Alex
Indeed, at the very least it's a source location to put a breakpoint at. It doesn't pollute the output of what() where meaningful messages have been put in, but does supplement diagostic_information(...), which I at least only output to internally-visible or debug streams; not user-visible messages.
participants (6)
-
Alex Perry
-
Emil Dotchevski
-
Roger Martin
-
Rowan James
-
Sebastian Redl
-
Vladimir Prus