lmi
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[lmi] Stylistic question about constructing error messages


From: Vadim Zeitlin
Subject: [lmi] Stylistic question about constructing error messages
Date: Fri, 12 Feb 2016 15:01:14 +0100

 Hello,

 There are many checks for the input data in the SOA tables code that I'm
writing and each of them throws an exception if it fails. Most of them also
try to provide as much information as possible about what exactly went
wrong because nothing is more aggravating than running a command merging
in a hundred of files and getting "invalid data" error without any more
details. So a typical check looks like this:

    if(num > max_num)
        {
        std::ostringstream oss;
        oss << "value for numeric field '"
            << name
            << "' is out of range (maximum allowed is "
            << max_num
            << ") at line "
            << line_num
            ;
        throw std::runtime_error(oss.str());
        }

 So far so good, but there are _many_ of them. I was writing all the checks
in full so far because I wanted to keep things simple, but this is getting
really tiresome, so I'd like to ask you what do you think about some
alternatives, i.e. to choose from

0. Do nothing special, continue writing the code like above in full.

1. Use a simple macro like LMI_ASSERT_WITH_MSG, i.e. rewrite the above as

        THROW_WITH_MSG
            (std::runtime_error
            ,"value for numeric field '"
                << name
                << "' is out of range (maximum allowed is "
                << max_num
                << ") at line "
                << line_num
            );

   This is very simple to do, but is rather ugly.

2. Use a macro for just the message part, i.e. rewrite the above as

        throw std::runtime_error(MAKE_MESSAGE
            ("value for numeric field '"
                << name
                << "' is out of range (maximum allowed is "
                << max_num
                << ") at line "
                << line_num
            ));

   This is slightly less simple to do as we need a helper object inside
   the MAKE_MESSAGE() macro, but is less ugly and could also be used in
   other similar situations in the future (i.e. if we had this, we wouldn't
   have needed LMI_ASSERT_WITH_MSG in the first place).

2b. Avoid macros entirely and write things like this:

        throw std::runtime_error
            (MessageMaker("value for numeric field '")
                << name
                << "' is out of range (maximum allowed is "
                << max_num
                << ") at line "
                << line_num
            );

   This is basically the same as above, except it trades uniformity of
   the expression for the absence of macros.

3. As we're now using C++11, we also can use safe vararg functions and
   do things like this:

        throw std::runtime_error(make_message
            ("value for numeric field '"
            ,name
            ,"' is out of range (maximum allowed is "
            ,max_num
            ,") at line "
            ,line_num
            ));

   I don't know if this is better or worse than the version with "<<" to be
   honest. It's slightly more difficult to implement, but not by much,
   really. And it's completely macro-free and reusable.

3b. A slight variation would be

        throw make_error<std::runtime_error>
            ("value for numeric field '"
            ,name
            ,"' is out of range (maximum allowed is "
            ,max_num
            ,") at line "
            ,line_num
            );

    which gets rid of the extra pair of parentheses.


 Which version would you prefer? I've started doing (1) but, after stopping
to think for a while, I realized that this wasn't the best choice and my
current favourite is (3b). Which one is yours?

 If possible, I'd like to decide what to do about these checks relatively
soon because I'm continuing to write more of them and I'd rather change the
existing ones first and write the new ones in the new style than continue
writing them out explicitly as (0) and changing them later.

 Thanks in advance!
VZ

reply via email to

[Prev in Thread] Current Thread [Next in Thread]