Talk About Network



Register and Login
Nick
Password
Register create new account Sign up is FREE and you can post replies, new topics, bookmark posts and more!
Recover lost password


Programming > C++ Moderated > A chained excep...
Latest [ Topics | Posts ] Archive Post A New Topic Post a Reply
<< Topic < Post Post 1 of 8 Topic 9566 of 9593
Post > Topic >>

A chained exception (base) class for C++

by "Martin T." <0xCDCDCDCD@[EMAIL PROTECTED] > Apr 30, 2008 at 10:43 AM

Hi all,

I'm currently trying to come up with a decent exception base class for
some modules of ours and was thinking about adding exception-chaining
(yes, like in Java :-)
The following points where important for me:
* Must inherit from std::exception
* Should allow for a std::exception to be the start of the exception
chain.
* throw by value / catch by const reference

As exception chaining seems to be rather obscure with C++, I'm
interested what other think about the solution (find code below).

thanks,
br,
Martin



--CODE--
[**** Usage would then roughly be like this ***]
using namespace std;
using namespace my_project_ns;

void f3e() {
	throw std::runtime_error("Any std::exception will do ...");
}

void f2e() {
	try {
		f3e();
	}
	catch(std_exc_catch_t e) {
		throw chained_exception("My exc", &e);
	}
}

void f1() {
	try {
		f2e();
	} catch(ch_exc_catch_t ce) {
		print_exc_chain(ce); // or do something else with the exception
	}
}

int main(int argc, char* argv)
{
	f1();
	return 0;
}


--CODE--
[**** header ****]
namespace my_project_ns {

////////////////////////////////////////////////////////////
class chained_exception :	virtual public std::exception
{
private:
	// No copy operator is needed.
	chained_exception& operator=(const chained_exception&);
public:
	chained_exception(const chained_exception&);
	chained_exception();
	chained_exception(const std::string&);

	typedef const std::exception*  exc_ref_t;
	chained_exception(const exc_ref_t exc_cause);
	chained_exception(const std::string& msg, exc_ref_t exc_cause);
	virtual chained_exception* clone() const;
	virtual ~chained_exception();

	virtual const char *what() const;

	bool  has_cause() const;
	const chained_exception *const chained_cause() const;
	const char *cause_typename() const;
	const char *cause_what() const;

private:
	typedef const chained_exception* chn_exc_ref_t;
	const std::string   m_msg;
	const std::string   m_cause_typename;
	const std::string   m_cause_msg;
	      chn_exc_ref_t m_cause;
};

////////////////////////////////////////////////////////////
typedef const std::exception&     std_exc_catch_t;
typedef const chained_exception&  ch_exc_catch_t;

////////////////////////////////////////////////////////////
void print_exc_chain(ch_exc_catch_t ce);

}; // namespace my_project_ns


[**** implementation ****]
#include "chained_exception.h"

namespace my_project_ns {

using namespace std;

////////////////////////////////////////////////////////////
chained_exception::chained_exception(const chained_exception& other)
: exception(other),
	m_msg(other.m_msg),
	m_cause_typename(other.m_cause_typename),
	m_cause_msg(other.m_cause_msg),
	m_cause(NULL)
{
	if(other.m_cause)
		m_cause = other.m_cause->clone();
}

////////////////////////////////////////////////////////////
chained_exception::chained_exception()
: exception(),
	m_msg(),
	m_cause_typename(),
	m_cause_msg(),
	m_cause(NULL)
{
}

////////////////////////////////////////////////////////////
chained_exception::chained_exception(const string& msg)
: exception(),
	m_msg(msg),
	m_cause_typename(),
	m_cause_msg(),
	m_cause(NULL)
{
}

////////////////////////////////////////////////////////////
chained_exception::chained_exception(exc_ref_t exc_cause)
: exception(),
	m_msg(),
	m_cause_typename(typeid(*exc_cause).name()),
	m_cause_msg(exc_cause->what()),
	m_cause(NULL)
{
	chn_exc_ref_t p = dynamic_cast<chn_exc_ref_t>(exc_cause);
	if(p)
		m_cause = p->clone();
}

////////////////////////////////////////////////////////////
chained_exception::chained_exception(const string& msg, exc_ref_t
exc_cause)
: exception(),
	m_msg(msg),
	m_cause_typename(typeid(*exc_cause).name()),
	m_cause_msg(exc_cause->what()),
	m_cause(NULL)
{
	chn_exc_ref_t p = dynamic_cast<chn_exc_ref_t>(exc_cause);
	if(p)
		m_cause = p->clone();
}

////////////////////////////////////////////////////////////
// virtual
chained_exception* chained_exception::clone() const
{
	return new chained_exception(*this);
}

////////////////////////////////////////////////////////////
// virtual
chained_exception::~chained_exception()
{
	if(m_cause)
		delete m_cause;
	m_cause = NULL;
}	

////////////////////////////////////////////////////////////
bool chained_exception::has_cause() const
{
	return !m_cause_typename.empty();
}

////////////////////////////////////////////////////////////
const chained_exception *const chained_exception::chained_cause() const
{
	return m_cause;
}

////////////////////////////////////////////////////////////
const char *chained_exception::cause_typename() const
{
	return m_cause_typename.c_str();
}

////////////////////////////////////////////////////////////
const char *chained_exception::cause_what() const
{
	return m_cause_msg.c_str();
}

////////////////////////////////////////////////////////////
const char *chained_exception::what() const
{
	return m_msg.c_str();
}


////////////////////////////////////////////////////////////
void print_exc_chain(ch_exc_catch_t ce) {
	cout << "* Exception * "
		   << typeid(ce).name()
			 << ": "
			 << ce.what()
			 << "\n";
	
	std::string indent(" ");
	for(const chained_exception* next=&ce; next; next =
next->chained_cause()) {
		if(next->has_cause()) {
			cout << "* caused by * "
				   << indent.c_str()
					 << next->cause_typename()
					 << ": "
					 << next->cause_what()
					 << "\n";
		}
		indent.push_back(' ');
	}
}

}; // namespace my_project_ns

-- 
      [ See http://www.gotw.ca/resources/clcm.htm
for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]




 8 Posts in Topic:
A chained exception (base) class for C++
"Martin T." <  2008-04-30 10:43:22 
Re: A chained exception (base) class for C++
=?UTF-8?B?RXJpayBXaWtzdHL  2008-04-30 17:05:07 
Re: A chained exception (base) class for C++
Greg Herlihy <greghe@[  2008-04-30 22:19:30 
Re: A chained exception (base) class for C++
Martin T <0xCDCDCDCD@[  2008-05-01 13:14:31 
Re: A chained exception (base) class for C++
Eugene Gershnik <gersh  2008-05-02 04:43:58 
Re: A chained exception (base) class for C++
nickf3 <nickf3@[EMAIL   2008-05-02 04:44:00 
Re: A chained exception (base) class for C++
Martin T <0xCDCDCDCD@[  2008-05-02 12:48:14 
Re: A chained exception (base) class for C++
Martin T <0xCDCDCDCD@[  2008-05-02 12:47:51 

Post A Reply:
  Go here to Signup

AddThis Feed Button


About - Advertising - Contact - Frequently Asked Questions - Privacy Policy - Terms of Use - Signup

Contact
tan12V112 Wed May 14 19:07:38 CDT 2008.