Search code examples
c++exceptionstliostreamstreambuf

C++ STL streambuf exception handling


Here I have this streambuf, ostream structure (modified from here http://wordaligned.org/articles/cpp-streambufs), where I try to throw from two points in the code. But I never can catch those exceptions in the main() and the program exits normally. What's the reason for this?

#include <iostream>
#include <fstream>
#include <streambuf>

using namespace std;

class teebuf: public streambuf
{
public:
        teebuf(streambuf * sb1, streambuf * sb2)
        : sb1(sb1) ,
        sb2(sb2)
    { }
private:
    virtual int overflow(int c) {
        if (c == EOF)
            return !EOF;
        else {
//Throwing here
            throw exception();
            int const r1 = sb1->sputc(c);
            int const r2 = sb2->sputc(c);
            return r1 == EOF || r2 == EOF ? EOF : c;
        }
    }

    virtual int sync() {
//Throwing here
        throw exception();
        int const r1 = sb1->pubsync();
        int const r2 = sb2->pubsync();
        return r1 == 0 && r2 == 0 ? 0 : -1;
    }   
private:
    streambuf * sb1;
    streambuf * sb2;
};

class teestream : public ostream
{
public:
    teestream(ostream & o1, ostream & o2);
private:
    teebuf tbuf;
};

teestream::teestream(ostream & o1, ostream & o2)
    :   std::ostream(&tbuf) ,
        tbuf(o1.rdbuf(), o2.rdbuf()) 
{ }

int main() {
    ofstream log("hello-world.log");
    teestream tee(cout, log);
    try {
        tee << "Hello, world!\n";
    } catch(...) {
//Catching here
        cerr << "Exception" << endl;
    }
    return 0;
}

Solution

  • The streams are set up by default to have an exeption mask catching everything. If you want to exceptions to propagate through the streams you'll need to set the exception mask to allow doing so.

    Specifically you'll need to set std::ios_base::badbit to get exceptions rethrown (after std::ios_base::badbit is set on the stream):

    stream.exceptions(std::ios_base::badbit);