module Jellyfish

Constants

Cascade
GetValue
VERSION

Public Class Methods

new(app=nil;) click to toggle source

# File lib/jellyfish.rb, line 185
def initialize app=nil; @app = app; end

Private Class Methods

included(mod) click to toggle source

# File lib/jellyfish.rb, line 251
def self.included mod
  mod.__send__(:extend, DSL)
  mod.__send__(:attr_reader, :app)
  mod.handle_exceptions(true)
end

Public Instance Methods

call(env) click to toggle source
# File lib/jellyfish.rb, line 187
def call env
  ctrl = self.class.controller.new(self.class.routes, self)
  case res = catch(:halt){ ctrl.call(env) }
  when Cascade
    cascade(ctrl, env)
  when Response
    handle(ctrl, res, env['rack.errors'])
  when Array
    res
  when NilClass # make sure we return rack triple
    ctrl.block_call(nil, lambda{|_|_})
  else
    raise TypeError.new("Expect the response to be a Jellyfish::Response" \
      " or Rack triple (Array), but got: #{res.inspect}")
  end
rescue => e
  handle(ctrl, e, env['rack.errors'])
end
log(msg, stderr) click to toggle source
# File lib/jellyfish.rb, line 211
def log msg, stderr
  return unless stderr
  stderr.puts("[#{self.class.name}] #{msg}")
end
log_error(e, stderr) click to toggle source
# File lib/jellyfish.rb, line 206
def log_error e, stderr
  return unless stderr
  stderr.puts("[#{self.class.name}] #{e.inspect} #{e.backtrace}")
end
public_root() click to toggle source

# File lib/jellyfish.rb, line 260
def public_root
  "#{File.dirname(__FILE__)}/jellyfish/public"
end

Private Instance Methods

best_handler(e) click to toggle source
# File lib/jellyfish.rb, line 236
def best_handler e
  handlers = self.class.handlers
  if handlers.key?(e.class)
    handlers[e.class]
  else # or find the nearest match and cache it
    ancestors         = e.class.ancestors
    handlers[e.class] = handlers.dup. # thread safe iteration
      inject([nil, Float::INFINITY]){ |(handler, val), (klass, block)|
        idx = ancestors.index(klass) || Float::INFINITY # lower is better
        if idx < val then [block, idx] else [handler, val] end }.first
  end
end
cascade(ctrl, env) click to toggle source
# File lib/jellyfish.rb, line 217
def cascade ctrl, env
  app.call(env)
rescue => e
  handle(ctrl, e, env['rack.errors'])
end
handle(ctrl, e, stderr=nil) click to toggle source
# File lib/jellyfish.rb, line 223
def handle ctrl, e, stderr=nil
  if handler = best_handler(e)
    ctrl.block_call(e, handler)
  elsif !self.class.handle_exceptions
    raise e
  elsif e.kind_of?(Response) # InternalError ends up here if no handlers
    [e.status, e.headers, e.body]
  else # fallback and see if there's any InternalError handler
    log_error(e, stderr)
    handle(ctrl, InternalError.new)
  end
end