Raising a different exception in "after" or "after_raising" advice

Posted by Dean Wampler Sat, 26 Apr 2008 21:13:04 GMT

An Aquarium user asked recently if you can use after_raising advice to raise a different exception, e.g., 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!)

The following made-up example illustrates what you can do. Imagine you are one of the handful of Ruby programmers who aren’t using ActiveRecord ;) and you have an OracleDriver class that handles Oracle database transactions.


class OracleDriver
  class OracleDriverException < StandardException; ...; end
  class ConnectionError < OracleDriverException; ...; end
  def connect
    if try_to_connect == false
      raise ConnectionError 
    end
    ...
  end
  def find query_parameters
    ...
  end
end

In the application code that uses the OracleDriver you ignore any exceptions raised (because we will implement an exception handling strategy elsewhere…).


  ...
  def load_object oracle_driver, query_parameters
    oracle_driver.connect
    oracle_driver.find query_parameters
  end
  ...

Finally, you implement an application-wide exception handling strategy for any exceptions raised by the driver.


Aspect.new :after_raising => OracleDriverException, 
    :in_types => ... 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

In other words, any exceptions raised by calls to OracleDriver are wrapped in an ApplicationException, which will be thrown by Aquarium when the advice block finishes.

This technique can also be used when handling exceptions in after advice.

By the way, in a similar way, you can also change the return value in after and after_returning advice. In this case, you assign a new value to jp.context.returned_value.

Posted in ,  | no comments

Short presentation Aquarium

Posted by Dean Wampler Thu, 03 Apr 2008 10:37:23 GMT

I just posted the PDF for a short (30 minute) presentation on Aquarium that I presented to the aspect-oriented programming research community at the Aspect-Oriented Software Development 2008 Conference. It assumes some familiarity with aspects, but not much experience with Ruby. The talk was based on my Industry Track paper.

There is a longer presentation on Aquarium on my papers page, which is better if you are new to AOP (although the syntax shown in the Aquarium examples is a bit dated…).

no comments