Class: Harbor::Application

Inherits:
Object
  • Object
show all
Includes:
Events
Defined in:
lib/harbor/application.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Events

included, #raise_event

Constructor Details

#initialize(services, *args) ⇒ Application

Returns a new instance of Application.



28
29
30
31
32
33
34
35
36
37
# File 'lib/harbor/application.rb', line 28

def initialize(services, *args)
  unless services.is_a?(Harbor::Container)
    raise ArgumentError.new("Harbor::Application#services must be a Harbor::Container")
  end

  @services = services

  @router = (!args.empty? && !args[0].is_a?(String) && args[0].respond_to?(:match)) ? args.shift : self.class.routes(@services)
  @environment = args.last || "development"
end

Instance Attribute Details

#environmentObject (readonly)

Returns the value of attribute environment.



26
27
28
# File 'lib/harbor/application.rb', line 26

def environment
  @environment
end

#routerObject (readonly)

Returns the value of attribute router.



26
27
28
# File 'lib/harbor/application.rb', line 26

def router
  @router
end

#servicesObject (readonly)

Returns the value of attribute services.



26
27
28
# File 'lib/harbor/application.rb', line 26

def services
  @services
end

Class Method Details

.routes(services) ⇒ Object

Routes are defined in this method. Note that Harbor does not define any default routes, so you must reimplement this method in your application.

Raises:

  • (NotImplementedError)


22
23
24
# File 'lib/harbor/application.rb', line 22

def self.routes(services)
  raise NotImplementedError.new("Your application must redefine #{self}::routes.")
end

Instance Method Details

#call(env) ⇒ Object

Request entry point called by Rack. It creates a request and response object based on the incoming request environment, checks for public files, and dispatches the request.

It returns a rack response hash.



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/harbor/application.rb', line 46

def call(env)
  env["APP_ENVIRONMENT"] = environment
  request = Request.new(self, env)
  response = Response.new(request)

  catch(:abort_request) do
    if file = find_public_file(request.path_info[1..-1])
      response.cache(nil, ::File.mtime(file), 86400) do
        response.stream_file(file)
      end

      return response.to_a
    end

    handler = @router.match(request)

    dispatch_request(handler, request, response)
  end

  response.to_a
end

#default_layoutObject



149
150
151
# File 'lib/harbor/application.rb', line 149

def default_layout
  warn "Harbor::Application#default_layout has been deprecated. See Harbor::Layouts."
end

#dispatch_request(handler, request, response) ⇒ Object

Request dispatch function, which handles 404’s, exceptions, and logs requests.



72
73
74
75
76
77
78
79
80
81
82
# File 'lib/harbor/application.rb', line 72

def dispatch_request(handler, request, response)
  start = Time.now

  return handle_not_found(request, response) unless handler

  handler.call(request, response)
rescue StandardError, LoadError, SyntaxError => e
  handle_exception(e, request, response)
ensure
  raise_event(:request_complete, request, response, start, Time.now)
end

#find_public_file(file) ⇒ Object

:nodoc:



142
143
144
145
146
147
# File 'lib/harbor/application.rb', line 142

def find_public_file(file) #:nodoc:
  public_path = Pathname(self.class.respond_to?(:public_path) ? self.class.public_path : "public")
  path = public_path + file

  path.file? ? path : nil
end

#handle_exception(exception, request, response) ⇒ Object

Method used to nicely handle uncaught exceptions.

Logs full error messages to the configured ‘error’ logger.

By default, it will render “We’re sorry, but something went wrong.”

To use a custom 500 message, create a view “exceptions/500.html.erb”, and optionally create a view “layouts/exception.html.erb” to style it.



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/harbor/application.rb', line 118

def handle_exception(exception, request, response)
  response.flush
  response.status = 500

  trace = build_exception_trace(exception, request)

  if environment == "development"
    response.content_type = "text/html"
    response.puts(Rack::ShowExceptions.new(nil).pretty(request.env, exception))
  else
    response.layout = "layouts/exception" if Harbor::View.exists?("layouts/exception")

    if Harbor::View.exists?("exceptions/500.html.erb")
      response.render "exceptions/500.html.erb", :exception => exception
    else
      response.puts "We're sorry, but something went wrong."
    end
  end

  raise_event(:exception, exception, request, response, trace)

  nil
end

#handle_not_found(request, response) ⇒ Object

Method used to nicely handle cases where no routes or public files match the incoming request.

By default, it will render “The page you requested could not be found”.

To use a custom 404 message, create a view “exceptions/404.html.erb”, and optionally create a view “layouts/exception.html.erb” to style it.



93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/harbor/application.rb', line 93

def handle_not_found(request, response)
  response.flush
  response.status = 404

  response.layout = "layouts/exception" if Harbor::View.exists?("layouts/exception")

  if Harbor::View.exists?("exceptions/404.html.erb")
    response.render "exceptions/404.html.erb"
  else
    response.puts "The page you requested could not be found"
  end

  raise_event(:not_found, request, response)
end