Chapter 2. Exception Handling and Debugging

Table of Contents

Debugging BDB XML Applications

Before continuing, it is helpful to look at exception handling and debugging tools in the BDB XML API.

All BDB XML operations can throw an exception, and so they should be within a try block.

BDB XML methods throw XmlException objects. BDB XML always re-throws all underlying Berkeley DB exceptions as XmlException, so every exception that can be thrown by BDB XML is an XmlException instance.

XmlException is derived from std::exception, so you are only required to catch std::exception in order to provide proper exception handling for your BDB XML applications. Of course, you can choose to catch both types of exceptions if you want to differentiate between the two in your error handling or messaging code.

Note that if you are using core Berkeley DB operations with your BDB XML application then you should catch either DbException or std::exception with this code.

The following example illustrates BDB XML exception handling.

#include "DbXml.hpp"

using namespace DbXml;
int main(void)
{
    // Open an XmlManager and an XmlContainer.
    XmlManager myManager;
    try {
        XmlContainer myContainer = 
            myManager.openContainer("container.dbxml");
    } catch (XmlException &xe) {
        // Error handling goes here
    } catch (std::exception &e) {
        // Error handling goes here
    }
} 

Note that, you can obtain more information on the cause of the XmlException by examining the underlying error code. Do this using the XmlException::getExceptionCode() method. See the Berkeley DB XML C++ API Reference Guide reference for details on the exception codes available through this class.

Debugging BDB XML Applications

In some cases, the exceptions thrown by your BDB XML application may not contain enough information to allow you to debug the source of an error. For this reason, it is always a good idea to create a custom error handler.

Once you have implemented your error handler, you make it known to you BDB XML application using DB_ENV->set_errcall()

For example:

#include "DbXml.hpp"

using namespace DbXml;

void
errcall_fun(const DB_ENV *dbenv,
              const char *errpfx,
              const char *msg) {
   std::cerr << errpfx << " : " << msg << std::endl; 
}

int main(void)
{
    // Open an XmlManager
    DB_ENV *myEnv;
    XmlManager myManager;

    myEnv = myManager.getDB_ENV();
    myEnv->set_errcall(myEnv, errcall_fun);
} 

Once you have set up your error handler, you can control the amount of information that BDB XML reports to that handler using setLogLevel() and setLogCategory().

setLogLevel() allows you to indicate the level of logging that you want to see (debug, info, warning, error, or all of these).

setLogCategory() allows you to indicate the portions of DB XML's subsystems for which you want logging messages issued (indexer, query processor, optimizer, dictionary, container, or all of these).

#include "DbXml.hpp"

using namespace DbXml;
int main(void)
{
    ...
    // Skipped environment and manager open
    ...
    try {
        XmlContainer myContainer = db.openContainer("container.dbxml");
        DbXml::setLogLevel(DbXml::LEVEL_ALL, true);
        DbXml::setLogCategory(DbXml::CATEGORY_ALL, true); 
    } catch (XmlException &xe) {
        // Error handling goes here
    } catch (std::exception &e) {
        // Error handling goes here
    }
}