[odb-users] Catch Exception Problem
Tarik BENZ
tenchu.tarik at hotmail.fr
Thu May 30 12:15:52 EDT 2013
Thank you very much, now the exception is caught.
Best
Tarik
> Date: Thu, 30 May 2013 12:03:52 -0400
> From: boris at codesynthesis.com
> To: tenchu.tarik at hotmail.fr
> CC: odb-users at codesynthesis.com
> Subject: Re: [odb-users] Catch Exception Problem
>
> Hi Tarik,
>
> Tarik BENZ <tenchu.tarik at hotmail.fr> writes:
>
> > The problem is that this exception is not caught by my code.
>
> All ODB exceptions derive from the odb::exception base, so if you
> catch that (as you do in your code), then you should be catching
> any ODB exception.
>
>
> > template<typename Type> bool CreateNewObject(Type * object)
> > {
> > if(object != NULL)
> > {
> > transaction * transact = NULL;
> > try
> > {
> > std::unique_ptr<odb::database> db (create_database());
> > transact = new transaction (db->begin());
> >
> > // Make object persistent.
> > db->persist((*object));
> > transact->commit();
> > }
> > catch (const odb::exception& e)
> > {
> > cerr << e.what () << endl;
> > if(transact != NULL)
> > {
> > transact->rollback();
> > }
> > }
> > }
> > return false;
> > }
>
> What can happen here is that the call to rollback() inside your
> exception handler can throw. This is actually a good example of
> how not to do it. Don't allocate the transaction object with new --
> just allocate it on the stack. If it is destroyed before commit()
> has been called (e.g., because an exception is thrown before you
> got a chance to call commit()), then it will automatically roll
> the transaction back. Also after certain failures (e.g., a connection
> is lost) it is pointless to try to call rollback. ODB is smart
> enough to handle that while your home-made auto-rollback is not.
>
> So, if I had to reimplement your code, it would look like this:
>
> template<typename Type> bool CreateNewObject(Type * object)
> {
> if(object != NULL)
> {
> try
> {
> std::unique_ptr<odb::database> db(create_database());
> transaction t (db->begin());
>
> // Make object persistent.
> db->persist(*object);
> t.commit();
>
> return true;
> }
> catch (const odb::exception& e)
> {
> cerr << e.what () << endl;
> }
> }
> return false;
> }
>
> Just realized another problem in your code: the database instance
> will no longer exist in the exception handler where you try to
> rollback the transaction started on this database. And the exception
> that you are unable to catch is most likely access violations.
>
> Boris
More information about the odb-users
mailing list