Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a better way to handle exceptions ? try-catch block is really ugly

I read this and find out it's important to handle exceptions, i use nlohmann::json (from github) and nearly in most of my member functions is use nlohmann::json::parse and nlohmann::json::dump which make a chance to throw exceptions if the input has a problem.

So I need to handle those chance of throwing exception something like this:

bool my_class::function(const std::string& input) const
try
{
    using namespace nlohmann;

    const auto result = json::parse(input);
    const auto name = result["name"].dump();

    /* and ... */
}
catch (const std::exception& e)
{
    /* handle exception */
}

But i want to know which line of the code throw exception, so if i write something like this:

bool my_class::function(const std::string& input) const
{
    using namespace nlohmann;

    try
    {
        const auto result = json::parse(input);
    }
    catch(const std::exception& e)
    {
        /* handle exception */
    }

    try
    {
        const auto name = result["name"].dump();
    }
    catch(const std::exception& e)
    {
        /* handle exception */
    }

    /* and ... */
}

It left me with thousands of try-catch blocks. It's a better why to handle exception ?

like image 231
Kate Avatar asked Jan 25 '23 23:01

Kate


2 Answers

As you might have noticed, C++ doesn't have this information available. @ΦXocę웃Пepeúpaツ provides some good workaround.

Let me provide some other point of view, as an end-user of your program, I'm not interested in the line of code on which the program failed. Either the JSON I'm providing is correct or it's incorrect. In the second case, I want to know what I need to do in order to fix the JSON. Looking at the code defining the exceptions, this looks really detailed.

The moment you are interested in it is when you wrote a bug in your program and you are getting unexpected errors. At that point in time, you better attach a debugger to your program and step through it while breaking on the throw of any exception. This will give you not only the line number, though also all information available on the stack ... I can recommend writing unit tests on your code, so you have small pieces of code that you have to debug. Ideally, you can even reduce the failure case to a new unit test if you still encounter an uncovered bug in your program.

Finally, the argument of performance. Having more details requires to collect more details. This collecting comes at a cost. In other programming languages, like Java, you can ask a call stack to your exception, in C++, exceptions are at its bare minimum. Although keeping track of a line number might not be that expensive, it does require extra assembly instructions that ain't needed for your end-user.

In short, the language doesn't provide a convenient way to get the line number. This because there are better ways to get this information and much more: your debugger.

like image 27
JVApen Avatar answered Jan 28 '23 19:01

JVApen


I would go like this: set a "sequence pointer" to keep the record of where/what are you trying to parse, like with a string with the pattern trying to parse a... so you can know/notify where exactly was the faulty element in the json.

look in the example below, if "name is faulty, then r is holding the value "trying to parse name" so in the exception you have the information about what json element is causing the problem :)

bool my_class::function(const std::string& input) const
{
    std::string r{""};
    try
    {
        using namespace nlohmann;
        r="trying to parse input";
        const auto result = json::parse(input);

        r="trying to parse name";
        const auto name = result["name"].dump();

        r="trying to parse age";
        const auto age = result["age"].dump();

        /* and ... */
    }
    catch (const std::exception& e)
    {
        /* handle exception */
    }
}
like image 188
ΦXocę 웃 Пepeúpa ツ Avatar answered Jan 28 '23 17:01

ΦXocę 웃 Пepeúpa ツ