Dean Wampler's Mind: Raising a different exception in "after" or "after_raising" advice /articles/2008/04/26/raising-a-different-exception-in-after-or-after_raising-advice en-us 40 Ruminations and Ruinations on Software Raising a different exception in &quot;after&quot; or &quot;after_raising&quot; advice <p>An <a href="http://aquarium.rubyforge.org">Aquarium</a> user asked recently if you can use <tt>after_raising</tt> advice to raise a different exception, <i>e.g.,</i> to wrap the original exception. Now you can, with the commits I did today. (This change will appear in the forthcoming V0.4.2 release.) Actually, this feature was partially implemented already, but never finished (OOPS!)</p> <p>The following made-up example illustrates what you can do. Imagine you are one of the handful of Ruby programmers who <i>aren&#8217;t</i> using ActiveRecord ;) and you have an OracleDriver class that handles Oracle database transactions. <pre> <code> class OracleDriver class OracleDriverException &lt; StandardException; ...; end class ConnectionError &lt; OracleDriverException; ...; end def connect if try_to_connect == false raise ConnectionError end ... end def find query_parameters ... end end </code> </pre> <p>In the application code that uses the <tt>OracleDriver</tt> you ignore any exceptions raised (because we will implement an exception handling strategy elsewhere&#8230;).</p> <pre> <code> ... def load_object oracle_driver, query_parameters oracle_driver.connect oracle_driver.find query_parameters end ... </code> </pre> <p>Finally, you implement an application-wide exception handling strategy for any exceptions raised by the driver.</p> <pre> <code> Aspect.new :after_raising =&gt; OracleDriverException, :in_types =&gt; ... do |jp, object, *args| # Ruby needs a standard way to wrap one exception in another. original = jp.context.raised_exception app_exception = ApplicationException.new(original.message) app_exception.set_backtrace(original.backtrace) jp.context.raised_exception = app_exception end </code> </pre> <p>In other words, any exceptions raised by calls to OracleDriver are wrapped in an <tt>ApplicationException</tt>, which will be thrown by Aquarium when the advice block finishes.</p> <p>This technique can also be used when handling exceptions in <tt>after</tt> advice.</p> <p>By the way, in a similar way, you can also change the return value in <tt>after</tt> and <tt>after_returning</tt> advice. In this case, you assign a new value to <tt>jp.context.returned_value</tt>.</p> Sat, 26 Apr 2008 16:13:04 -0500 urn:uuid:4e652833-7bfc-4336-b0a3-514d83fd53dc Dean Wampler http://blog.aspectprogramming.com/articles/2008/04/26/raising-a-different-exception-in-after-or-after_raising-advice AOP Aquarium http://blog.aspectprogramming.com/articles/trackback/54