[Rg 56] Re: Dispatching errors to current controller

Lars Olsson lasso at lassoweb.se
Wed Jul 18 15:06:01 EDT 2007


Jonathan Buch skrev:
>> I'm not sure how hard it would be to change, but I think it would be
>> better if it worked along the following lines:
>>
>> 1. First, check if the current controller has an error action/template
>> pair. If that is the case, call the current controller's error action.
>>
>> 2. If the current controller does not have an error action/template
>> pair, call the root controller's error action (/error).
> 
> Yes, maybe we can build a two-level lookup there, first using
> `Controller.current` and then Controller.get('/') to try and render the
> error page.  This makes errors even slower than they are right now, but
> ah well.  :)

I played around a bit (with depressing results):

module Ramaze
   module Dispatcher
     class Error
       ERROR_CODES = {Exception => 500, Ramaze::Error::NoAction => 404, 
Ramaze::Error::NoController => 404}

       class << self
         trait :last_error => nil

         def process error
           log_error(error)

           Thread.current[:exception] = error

           key = error.class.ancestors.find{ |a| ERROR_CODES[a] }
           status = ERROR_CODES[key || Exception]
           # This does not work since Controller.current seems to be nil 
at the time of the call...
           path = Controller.current.respond_to?(:error) ? 
R(Controller.current, :error) : '/error'

           unless error.message =~ %r(`#{path.split('/').last}')
             Response.current.status = status
             return Dispatcher.dispatch_to(path) if path and 
Global.error_page
           end

           Dispatcher.build_response(error.message, status)
         rescue Object => ex
           Inform.error(ex)
           Dispatcher.build_response(ex.message, status || 500)
         end

         def log_error error
           error_message = error.message

           if trait[:last_error] == error_message
             Inform.error(error_message)
           else
             trait[:last_error] = error_message
             Inform.error(error)
           end
         end

         def current
           Thread.current[:exception]
         end

       end
     end
   end
end

I don't understande the Dispatcher code too well, but has the controller 
thread really "died" at the time an exception is raised? Is it not 
possible to find out which controller instance that raised the exception?

/lasso


-- 
________________________________________
Lars Olsson
lasso at lassoweb.se
http://www.lassoweb.se/


More information about the Ramaze-general mailing list