module RocketIO class Controller # define error handlers # # @example define a handler that will process 404 errors # class Pages < RocketIO::Controller # # error 404 do |id| # "Sorry, looks like item with ID #{id.to_i} does not exists" # end # # def get id # item = Item.find_by(id: id) || error(404, id) # end # end # # @example define a handler that will process fatal errors # class Pages < RocketIO::Controller # # error 500 do |exception| # "Fatal error occurred: " + html_escape(exception.message) # end # # def get # # any exception raised here will be handled by the handler above # end # end # def self.error code, &block code = code.to_i code > 0 || raise(ArgumentError, 'Error code should be a number') block || raise(ArgumentError, 'block missing') (@__error_handlers__ ||= {})[code] = block define_error_handlers_methods end def self.define_error_handlers_methods source = self handlers = (source.instance_variable_get(:@__error_handlers__) || {}).each_with_object({}) do |(code,block),o| o[code] = :"__#{code}_error_handler__" private_api << define_method(o[code], &block) end handlers.update(allocate.error_handlers) return if handlers.empty? handlers.freeze private_api << define_method(:error_handlers) {handlers} end def error_handlers; RocketIO::EMPTY_HASH end # if there is a handler defined for given code it will be executed and the result used as body. # otherwise the `error` behaves exactly as `halt`. # # given args will be passed either to handler(if any defined) or to `halt` # def error code, *args error_handlers[code] || halt(code, *args) halt(code, __error__(code, *args)) end alias error! error # call defined error handler with given arguments. # # @raise NotImplementedError if no handler defined for given code # def __error__ code, *args error_handlers[code] || raise(NotImplementedError, 'No handler defined for %s error' % code.inspect) __send__(error_handlers[code], *args) end # 404: Not Found error 404 do RocketIO.error_renderer(404, xhr?, env: env) end # 409: Wrong number of arguments received error 409 do RocketIO.error_renderer(409, xhr?, { env: env, controller: self.class, resolved_path: url, expected_parameters: parameters_policy[env[RocketIO::REQUEST_METHOD]], received_parameters: path_params }) end # 501: Not Implemented error 501 do RocketIO.error_renderer(501, xhr?, env: env) end end end