Thread: exception handling wrapper functions?

  1. #1
    3735928559
    Join Date
    Mar 2008
    Location
    RTP
    Posts
    838

    exception handling wrapper functions?

    is it at all possible to do something like:

    Code:
    template <typename returnType,typename argType>tryFunc(typename (*func)(argType),argType arg)
    {
        try
        {
            func(arg);
        }
        catch(...)
        {
            //handle exception
        }
    }
    or do the try/catch blocks have to be hard coded into the blocks where the exception might occur?

    it would be extremely useful to me if there was a way to get out of having to write try/catch blocks around every piece of code i ever write...

  2. #2
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by m37h0d View Post
    it would be extremely useful to me if there was a way to get out of having to write try/catch blocks around every piece of code i ever write...
    Indeed, it is possible. But this is not the way...

    Can you explain a bit why you have to wrap "every piece of code you ever write?" That shouldn't be.

  3. #3
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    is it at all possible to do something like:
    What would replace the "handle exception" comment?

    it would be extremely useful to me if there was a way to get out of having to write try/catch blocks around every piece of code i ever write...
    You do not need to enclose in a try block code that will not emit exceptions. If you cannot appropriately handle or translate an exception at a particular level, allow it to propagate.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  4. #4
    3735928559
    Join Date
    Mar 2008
    Location
    RTP
    Posts
    838
    i've tried things like:
    Code:
    try
    {
        function();
    }
    catch(...)
    {
        handleException();
    }
    but the exception never seems to get caught if it occurs in the body of function().

    could you either point me to a good reference on this particular aspect of exception handling, or let me know what the right way would be?

    thanks!

  5. #5
    3735928559
    Join Date
    Mar 2008
    Location
    RTP
    Posts
    838
    Quote Originally Posted by laserlight View Post
    What would replace the "handle exception" comment?


    You do not need to enclose in a try block code that will not emit exceptions. If you cannot appropriately handle or translate an exception at a particular level, allow it to propagate.

    well, my strategy has always been to avoid exceptions from occurring in the first place, so i have a rather large body of work that does not include any exception handling. however, in the event something unusual happens, it would be nice if the exception were caught and information about it was logged (not to mention not interrupting the program's execution).

  6. #6
    The larch
    Join Date
    May 2006
    Posts
    3,573
    This sort of works for me, and boost can make it even a bit more versatile. However, I doubt you'd be able to make a function for any case where exceptions would be handled:

    Code:
    #include <iostream>
    #include <stdexcept>
    #include <boost/lambda/lambda.hpp>
    #include <boost/lambda/bind.hpp>
    
    //some functions that can throw
    void divide(int a, int b)
    {
        if (b == 0) {
            throw 1;
        }
        std::cout << a / b << '\n';
    }
    
    void print_range(int n)
    {
        if (n < 0)
            throw std::range_error("n is smaller than 0");
        for (int i = 0; i != n; ++i) {
            std::cout << i << ' ';
        }
        std::cout << '\n';
    }
    
    //dumb error handler
    template <class T>
    void alert(const T&)
    {
        std::cout << "An exception happened\n";
    }
    
    //slightly better error handler
    void print_error(const std::exception& e)
    {
        std::cout << e.what() << '\n';
    }
    
    template <class Except, class Func, class Response>
    void try_(Func f, Response r)
    {
        try {
            f();
        }
        catch (Except& e) {
            r(e);
        }
    }
    
    int main()
    {
        using namespace boost::lambda;
        try_<int>(bind(divide, 10, 2), alert<int>);
        try_<int>(bind(divide, 5, 0), alert<int>);
        try_<std::exception>(bind(print_range, -10), alert<std::exception>);
        try_<std::exception>(bind(print_range, -10), print_error);
        try_<std::exception>(bind(print_range, 5), print_error);
    }
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  7. #7
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    the exception never seems to get caught if it occurs in the body of function().
    O_o

    In my experience, this means the functions has been declared as "no throw" or resolves to an external/unfamiliar call frame.

    it would be nice if the exception were caught and information about it was logged
    O_O

    It would be nice if people stopped using exceptions in such a ridiculous fashion.

    However, I doubt you'd be able to make a function for any case where exceptions would be handled:
    Those exceptions aren't handled; they are logged and then ignored. You've even used function templates in such a way that if a specific exception handler was written it couldn't be used without adaptation of the calling code.

    Soma
    Last edited by phantomotap; 06-09-2008 at 10:39 AM.

  8. #8
    3735928559
    Join Date
    Mar 2008
    Location
    RTP
    Posts
    838
    Quote Originally Posted by phantomotap View Post
    O_O

    It would be nice if people stopped using exceptions in such a ridiculous fashion.

    Soma
    that's not helpful.

  9. #9
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    Quote Originally Posted by m37h0d View Post
    that's not helpful.
    Well, laserlight already smacked the ball out of the park with: "You do not need to enclose in a try block code that will not emit exceptions." and "If you cannot appropriately handle or translate an exception at a particular level, allow it to propagate.".

    Nothing more useful or more accurate can be added; I'm not sure I could even manage something more succinct.

    Soma

  10. #10
    3735928559
    Join Date
    Mar 2008
    Location
    RTP
    Posts
    838
    well, clearly you had ideas about how such a thing should be used. offering them up would have been nice.

    fwiw, i didn't say logging info about the exception would be all that's done. but in the event there isn't a handler written for it, then that's the most useful thing i can think of to do with it, so i can get the error log back to me from out in the field and write one.

    if you have a better idea, i'd love to be disabused of my ignorance.

  11. #11
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    well, clearly you had ideas about how such a thing should be used. offering them up would have been nice.
    Indeed, but I don't think you'll find: "Rewrite the code so functions spawning pointless exceptions use traditional return values for such errors." useful. There are any number of metrics for when to use exceptions, but usually I use this metric: if a "'try'/'catch' block" is necessary, don't bother with exceptions. (Yea, it sounds strange; I don't care.) Basically, if you must catch an exception for an error that doesn't alter program flow, you've failed. By the same metric: if you have caught an exception only to continue program flow, you've failed. And for again, if you require the employee of an "'if-'else' block" within a "'catch' block", you've failed. Yet again, if you do nothing but 'throw;', you've failed.

    (Unfortunately, this logic isn't satisfied by most code irrespective of the programmers desire. It is a sad state of affairs but because so many regurgitate the non-advice "use a small exception hierarchy derived from the standard exceptions" programmers of others' source must almost invariably break all of the above because the source must examine runtime values associated with a particular instance of an exception.)

    fwiw, i didn't say logging info about the exception would be all that's done.
    *sigh*

    And I didn't say that you were necessarily at fault; despite what you may think, it may not have been directed at you. Granted, if you wrote the code that spawns these pointless exceptions that can be so safely ignored, then it was directed at you. (Also, you follow that statement up with what comes out to "That's all I can think of; that's what I will do.")

    if you have a better idea, i'd love to be disabused of my ignorance.
    Honestly? I can't think of a single reason to approach exceptions, like fancy "'if'-'else'" statements, as a way to log an event. I was not being glib. I have never made this particular mistake, and I literally have no ideas for how to fix it. (Again, beyond a fresh design and a rewrite.) An exception mechanic isn't just something you can tack on; you are destined to have problems if logical exceptions weren't part of the original design. As far as I know if the original design raises pointless exceptions you only have two options: rewriting or wrapping. That wrapping such an interface may be the only valid option pretty much proves that something is wrong.

    I don't see how any of this helps your current predicament.

    Soma

  12. #12
    3735928559
    Join Date
    Mar 2008
    Location
    RTP
    Posts
    838
    so, judging what will and will not be of use to me based on specious assumptions aside, the whole point of this is that i have, hypothetically, failed somewhere. i'd need to be able to track down exactly what went wrong as quickly as possible, and if possible avoid interrupting subsequent operation of the program.

    bear in mind that if this occurs, i won't have any access to the machine generating the error whatsoever. i would have to rely on an operator or a field tech to submit a trouble report describing what they were doing when the error occurred.

    you think it would be pointless to have some information that said, for example: "Exception type error generated in function"?

    and yes, i already have the information available to provide function and error.

    Quote Originally Posted by phantomotap
    In my experience, this means the functions has been declared as "no throw" or resolves to an external/unfamiliar call frame.
    i'm not sure i completely understand this. the structure of what i have is similar to this:

    Code:
    void class1::func()
    {
        class2Instance->class2::doSomething();
    }
    is there any reason why this might have an external or unfamiliar call frame?
    Last edited by m37h0d; 06-09-2008 at 12:37 PM.

  13. #13
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    so, judging what will and will not be of use to me based on specious assumptions aside, the whole point of this is that i have, hypothetically, failed somewhere.
    "Specious"? If you say so...

    i'd need to be able to track down exactly what went wrong as quickly as possible, and if possible avoid interrupting subsequent operation of the program.
    If the source is as bad as originally posted code hints the only exceptions ever propagated will probably be real.

    you think it would be pointless to have some information that said, for example: "Exception type error generated in function"?
    It's worse that that. I know it would be pointless. In your case: badly designed exceptions may never be thrown, but when they are thrown will be logged along with real errors. You'll not be able to tell them apart simply because they have been logged. (Unless you already know where to look allowing you to use a different logging, "handling" wrapper for such cases, and if you already know where to look the logging function adds nothing.) Only a full source review could hope to find such design problems. In other words, you may find focus to fix an instance of the effect, but not the problem as I see it.

    is there any reason why this might have an external or unfamiliar call frame?
    ^_^

    Well, I would wager a guess... but it would be "based on specious assumption".

    (Actually, there is no correct answer. The 'class2' could be imported from a shared library from a different version of the same compiler. Any function compiled by a different version of the same compiler or different compiler is potentially from an external/unfamiliar call frame. Essentially, the exception could not propagate "up" because "up" is in a different stack, interpreted differently, or mangled differently than what the target mechanism actually expects meaning that the target mechanism can't actually process the exception. The results can be pretty entertaining... and painful.)

    Soma

  14. #14
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by phantomotap View Post
    (Actually, there is no correct answer. The 'class2' could be imported from a shared library from a different version of the same compiler. Any function compiled by a different version of the same compiler or different compiler is potentially from an external/unfamiliar call frame. Essentially, the exception could not propagate "up" because "up" is in a different stack, interpreted differently, or mangled differently than what the target mechanism actually expects meaning that the target mechanism can't actually process the exception. The results can be pretty entertaining... and painful.)

    Soma
    Quite possibly the right answer, however there is at the very least one other possibility:
    the exception is thrown by a function that has overwritten its call-stack, and all the compiler can do from that point is give up, since it can not find out where the call to the throwing funciton was coming from, and thus not be able to track back to the relevant "catch".

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  15. #15
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    I don't think I'd want to use this in production code, but I've used it in a QA test harness before:
    Code:
    #define TRY( func, file, line ) \
        try { \
            func; \
        } catch (...) { \
            cout << "Error!  Exception caught in " << file << ", line: " << line << endl; \
        }
    
    int main()
    {
        TRY( someThrowingFunc(), __FILE__, __LINE__ )
    ...
    }
    I'm not sure if that's what you were looking for?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Memory handling functions (newbie questions)
    By PaulBlay in forum C Programming
    Replies: 6
    Last Post: 03-10-2009, 06:37 AM
  2. An array of macro functions?
    By someprogr in forum C Programming
    Replies: 6
    Last Post: 01-28-2009, 07:05 PM
  3. Replies: 7
    Last Post: 11-17-2008, 01:00 PM
  4. CIN and exception handling
    By OldSchool in forum C++ Programming
    Replies: 4
    Last Post: 05-14-2006, 05:02 PM
  5. handling basic math functions
    By MyDestiny in forum C++ Programming
    Replies: 3
    Last Post: 03-02-2005, 01:12 PM

Tags for this Thread