libsex  3.1.0
simple exception library (C++)
Example

The unit tests serve as compilable and runnable documentation (not included in this API documentation).

At first, let's declare a very primitive exception in tests/framework/ExampleException1.hxx

/**
 * @file
 *
 * Shows how to _declare_ basic exception class.
 */

#ifndef EXAMPLEEXCEPTION1_HXX
#define EXAMPLEEXCEPTION1_HXX

#include <libsex/declare.hxx>
#include <libsex/Exception.hxx>


namespace example
{
        // Forward declare to ensure the namespace exists.
        class ExampleException1;
}


// ExampleException1 inherits from libsex::Exception.
LIBSEX_DECLARE(libsex::Exception, example, ExampleException1)

#endif

We then define it and assign an error message in tests/framework/ExampleException1.cxx

/**
 * @file
 * Shows how to _define_ a basic exception class.
 */

#include <libsex/define.hxx>
#include <libsex/Exception.hxx>
#include <tests/framework/ExampleException1.hxx>

// Define ExampleException1 and provide a message template.
// If you want to localize your exceptions, you just have
// to localize that line.

LIBSEX_DEFINE(libsex::Exception, example, ExampleException1, "Error!")

We repeat that procedure to create a more sophisticated class:

tests/framework/ExampleException2.hxx

/**
 * @file
 *
 * Shows how to _declare_ an exception class that uses
 * placedholders in its message template.
 *
 * Note that it is _declared_ in exactly the same way as a
 * basic exception class.
 */

#ifndef EXAMPLEEXCEPTION2_HXX
#define EXAMPLEEXCEPTION2_HXX

#include <libsex/declare.hxx>
#include <libsex/Exception.hxx>

namespace example
{
        class ExampleException2;
}

// ExampleException2 inherits from libsex::Exception.
LIBSEX_DECLARE(libsex::Exception, example, ExampleException2)

#endif

tests/framework/ExampleException2.cxx

/**
 * @file
 *
 * Shows how to _define_ an exception class that contains
 * placeholders in its message template.
 */

#include <libsex/define.hxx>
#include <libsex/Exception.hxx>
#include <tests/framework/ExampleException2.hxx>

// Define ExampleException2 and provide a message template
// (see printf for a list and explanation of placeholders).

LIBSEX_DEFINE(libsex::Exception, example, ExampleException2, "%s is %d")

Finally, here's how to use those classes and the framework:

tests/UsageExamples.cxx

/**
 * @file
 *
 * Shows how this framework is supposed to be used.
 */

// Needed for the tests in this file, not part of the examples.
#include <tests/UsageExamples.hxx>
#include <sstream>

// Usage examples begin now.

#include <libsex/throw.hxx>
#include <tests/framework/ExampleException1.hxx>
#include <tests/framework/ExampleException2.hxx>

/**
 * How to simply create an exception.
 */
void tests::UsageExamples::testSimpleConstruction()
{
        // The error message.
        std::string msg("Someone has set us up the bomb!");

        // Create an exception, do not throw it. Note we
        // can pass an arbitrary string as message --
        // the Exception subsystem itself does not depend
        // on message templates.
        example::ExampleException2 e(msg.c_str());

        // Turn description into an instance of std::string
        // (needed for comparing).
        std::string what(e.what());



        CPPUNIT_ASSERT_EQUAL(msg, what);
}

/**
 * How to throw a single exception without placeholders in
 * its message template.
 */
void tests::UsageExamples::testSimpleThrowing()
{
        bool success = false;

        try {
                // Create an instance and throw it. Note
                // that THROW uses the message template, so
                // we can not pass an arbitrary string.
                // Since ExampleException1's message
                // template does not expect any arguments,
                // we can use THROW_ARGLESS.
                THROW_ARGLESS(example::ExampleException1);
        } catch (example::ExampleException1& e) {
                // Check whether result is as expected.

                std::string exp(__FILE__);
                exp += ":55: Error!";
                std::string act(e.what());

                CPPUNIT_ASSERT_EQUAL(exp, act);
                success = true;
        }

        CPPUNIT_ASSERT(success);
}

/**
 * How to throw a single exception.
 */
void tests::UsageExamples::testThrowing()
{
        bool success = false;

        try {
                // Fill the parameters into the message
                // template and throw an exception
                // containing the resulting string.
                THROW(example::ExampleException2, "foobar", 42);
        } catch (example::ExampleException2& e) {
                // Check whether result is as expected.

                std::string exp(__FILE__);
                exp += ":81: foobar is 42";
                std::string act(e.what());

                CPPUNIT_ASSERT_EQUAL(exp, act);
                success = true;
        }

        CPPUNIT_ASSERT(success);
}

/**
 * How to chain exceptions.
 */
void tests::UsageExamples::testChaining()
{
        bool success = false;

        try {
                try {
                        THROW(example::ExampleException2, "foo", 21);
                } catch (example::ExampleException2& e) {
                        // Note that CHAIN expects the
                        // variable name of the previous
                        // exception to be "e"!
                        CHAIN(example::ExampleException2, "bar", 42);
                }
        } catch (example::ExampleException2& e) {
                // Check whether result is as expected.

                std::string exp(__FILE__);
                exp += ":110: bar is 42\n";
                exp += __FILE__;
                exp += ":105: foo is 21";

                std::stringstream act;
                e.backtrace(act);

                CPPUNIT_ASSERT_EQUAL(
                        exp,
                        act.str());

                success = true;
        }

        CPPUNIT_ASSERT(success);
}
 All Classes Files Functions Variables Defines