Thrown errors are uncatchable

Issue #47 invalid
Julie Iaccarino created an issue

It is not possible to catch errors thrown by libzdb during operation.

Code example below:

a arglist.v.list[1].v.str of “butts” will result in !url being true, and a successful handling of the incorrect input.

However a postgresql://user:localhost/moo url, or other ‘semi valid’ url, with incorrect or missing logging details causes a full SIG11 fault.

        url = URL_new(arglist.v.list[1].v.str);
        if (url)
        {
            try {
                TRY
                {
                    pool = ConnectionPool_new(url);    
                    if (!pool) {
                        ret->type = TYPE_ERR;
                        ret->v.err = E_PERM;    
                    }
                }
                ELSE {
                    ret->type = TYPE_ERR;
                    ret->v.err = E_PERM;
                }
                END_TRY;
            } catch (...) 
            {
                ret->type = TYPE_ERR;
                ret->v.err = E_PERM;
            }
        } else {
            ret->type = TYPE_ERR;
            ret->v.err = E_INVARG;
        }

Since these values can be provided during runtime of the application, this is a critical bug as it would be possible to crash the entire server.

Other SQLException errors are similarly uncatchable, even when using the macro patterns in Exception.h.

Comments (9)

  1. Tildeslash repo owner

    You cannot send a C++ string to URL_new which expect a c_str. From C++, you should import zdbpp.h instead and use this API

  2. Julie Iaccarino reporter

    Just to clarify are you saying there isn’t documentation for zdbpp.h, so using the idiomatic syntax present on the webpage examples will result in the c interface being used, causing anomalous behavior like what I’m seeing, and I should instead just puzzle out how to use the zdbpp.h interface from the header file itself?

  3. Julie Iaccarino reporter

    If that’s correct, updating the documentation would be fantastic, as that is not clear.

  4. Julie Iaccarino reporter

    I assumed I interpreted you correctly and I went ahead and made the change and received the same error.

            try {
                TRY
                {
                    ConnectionPool pool = ConnectionPool(arglist.v.list[1].v.str);    
                    if (!pool) {
                        ret->type = TYPE_ERR;
                        ret->v.err = E_PERM;    
                    }
                }
                ELSE {
                    ret->type = TYPE_ERR;
                    ret->v.err = E_PERM;
                }
                END_TRY;
            } catch (...) 
            {
                ret->type = TYPE_ERR;
                ret->v.err = E_PERM;
            }
    

    SIG11 and program failure.

  5. Julie Iaccarino reporter

    Some more information I’ve found: This happens only if I try to run this code off the main thread, if I run it on the main thread I actually do catch the exception.

  6. Tildeslash repo owner

    http://tildeslash.com/libzdb/#api demonstrates the main use cases for the C++ API. (scroll down to C++ examples). There is also this example code https://bitbucket.org/tildeslash/libzdb/src/master/test/zdbpp.cpp

    Best practice is to create and start the Connection Pool on the main thread. The Connection Pool is thread-safe, but initialisation of databases like MySQL, should be done on the main thread.

    Ps. Don’t use the C Exception macros in C++. Just use regular C++ try/catch

  7. Log in to comment