Hi~ On Jul 31, 2007, at 10:57 AM, ry dahl wrote:
> Since Merb has the lovely property of rendering the output of an > action, using ruby-level exceptions to render error pages in Merb > could be a cute way to approach error handling. > > Suppose one has an action for editing a product which you would like > to restrict to administrators: > > def edit > raise AdminAccessReqired unless session[:user] and session > [:user].admin? > @product = Product.find(params[:id]) > raise UnknownProduct if @product.nil? > render > end > > Where AdminAccessReqired and UnknownProduct are ControllerExceptions. > > The controller exception hierarchy would be rooted with the base > class, Merb::ControllerException. The Merb dispatcher would rescue any > exception which was a kind_of ControllerException. Derived from > ControllerException would be an exception for each of the HTTP error > codes. For example: > > module ControllerExceptions > > class Unauthorized < ControllerException > STATUS_CODE = 401 > # ... > > class Forbidden < ControllerException > STATUS_CODE = 403 > # ... > > class NotFound < ControllerException > STATUS_CODE = 404 > # ... > > Application authors could place addition derivations into > dist/app/exceptions. These must be children of an already defined Merb > controller exception class. The user defined exceptions would have a > method called 'action' which acts like typical controller action. It > is called to render a page when the exception is raised. For example > > # dist/app/exceptions/admin_access_required.rb > class AdminAccessRequired < Merb::ControllerExceptions::Unauthorized > def action > if session[:user].nil? > redirect '/login' > else > render # views/exceptions/admin_access_required.rhtml > end > end > end > > If the user is logged in but does not have administrative access, this > will render a page describing the problem with the proper HTTP status > code 401. > > The UnknownProduct exception might look like this: > > # dist/app/exceptions/unknown_product.rb > class UnknownProduct < Merb::ControllerExceptions::NotFound > def action > @id = params[:id] > render # views/exceptions/unknown_product.rhtml > end > end > > If passed a bad id, the server will respond with 404 and a page that > is specific to missing a product. > > The advantages of this scheme are > - Simplifies controller action definitions by placing exceptional > logic elsewhere > - Eases the conformity to HTTP by returning proper error codes > - Could allow for before and after filters around a restricted type of > exceptions (eg, for logging purposes) > - Further modularizes testing code: one needs only to check that an > action raise a particular exception > > Thoughts? > I would gladly implement this and submit a patch if the list thinks > this that it is a worth feature. > > The idea is from Robert Hahn: > http://blog.roberthahn.ca/articles/2007/06/22/setting-http-response- > codes-with-exceptions I like the idea in general but I am slightly concerned about using exceptions extensively for flow control like this because ruby exceptions are really resource intensive and slow as molasses. I've seen exception handling be the cpu bottleneck in a lot of production rails applications. Exceptions have to unwind the stack and setup a bunch of cointext stuff that makes them have a lot of overhead. I'd be willing to entertain the idea though as it does seem like a very nice api, but it would require benchmarking before I would put it in merb core. Can you make a small proof of concept patch that we can benchmark a bit and then decide? Cheers- -- Ezra Zygmuntowicz -- Founder & Ruby Hacker -- [EMAIL PROTECTED] -- Engine Yard, Serious Rails Hosting -- (866) 518-YARD (9273) _______________________________________________ Merb-devel mailing list [email protected] http://rubyforge.org/mailman/listinfo/merb-devel
