<html><head><meta http-equiv="Content-Type" content="text/html charset=windows-1252"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;">Honored twistedeers,<div><br></div><div><br></div><div>Consider the following (blocking) decorator, which runs a function in a transaction:</div><div><br></div><div><font face="Monaco">def _with_transaction(f):<br>    def decorated(self, *args, **kwargs):<br>        conn = self.engine.connect()<br>        txn = conn.begin()<br><br>        try:<br>            result = f(self, conn, *args, **kwargs)<br>        except:<br>            txn.rollback()<br>            raise<br>        else:<br>            txn.commit()<br>            return<br><br>    return decorated</font></div><div><div><br class="webkit-block-placeholder"></div><div>Where I to translate this logic verbatim to @inlineCallbacks, I get:</div><div><br></div><div><div><font face="Monaco">def _with_transaction(f):</font></div><div><font face="Monaco">    @inlineCallbacks</font></div><div><font face="Monaco">    def decorated(self, *args, **kwargs):</font></div><div><font face="Monaco">        conn = yield self.engine.connect()</font></div><div><font face="Monaco">        txn = yield conn.begin()</font></div><div><font face="Monaco"><br></font></div><div><font face="Monaco">        try:</font></div><div><font face="Monaco">            result = yield f(self, conn, *args, **kwargs)</font></div><div><font face="Monaco">        except:</font></div><div><font face="Monaco">            yield txn.rollback()</font></div><div><span style="font-family: Monaco;">            raise</span></div><div><font face="Monaco">        else:</font></div><div><font face="Monaco">            yield txn.commit()</font></div><div><font face="Monaco">            returnValue(result)</font></div><div><font face="Monaco"><br></font></div><div><font face="Monaco">    return decorated</font></div></div><div><br class="webkit-block-placeholder"></div><div>However, there’s a bug here! In the except clause: there’s an (implicit) current exception, to be re-raised by the bare raise statement. Unfortunately, when doing yield txn.rollback(), that conveniently eats said exception.</div><div><br></div><div>Of course, there’s a fairly simple workaround involving catching BaseException and capturing the exception instance explicitly.</div><div><br></div><div>I’m wondering if this is just a leaky abstraction, or if I should report it as a bug in @inlineCallbacks?</div><div><br class="webkit-block-placeholder"></div><div><br></div><div>cheers<br>lvh<br><br><br></div><br></div></body></html>