hanami-controller 2.0.0.beta4 → 2.0.0.rc1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8,9 +8,18 @@ require "hanami/action/cookie_jar"
8
8
  require "hanami/action/cache/cache_control"
9
9
  require "hanami/action/cache/expires"
10
10
  require "hanami/action/cache/conditional_get"
11
+ require_relative "errors"
11
12
 
12
13
  module Hanami
13
14
  class Action
15
+ # The HTTP response for an action, given to {Action#handle}.
16
+ #
17
+ # Inherits from `Rack::Response`, providing compatibility with Rack functionality.
18
+ #
19
+ # @see http://www.rubydoc.info/gems/rack/Rack/Response
20
+ #
21
+ # @since 2.0.0
22
+ # @api private
14
23
  class Response < ::Rack::Response
15
24
  # @since 2.0.0
16
25
  # @api private
@@ -26,7 +35,7 @@ module Hanami
26
35
 
27
36
  # @since 2.0.0
28
37
  # @api private
29
- attr_reader :request, :exposures, :format, :env, :view_options
38
+ attr_reader :request, :exposures, :env, :view_options
30
39
 
31
40
  # @since 2.0.0
32
41
  # @api private
@@ -46,7 +55,7 @@ module Hanami
46
55
  # @api private
47
56
  def initialize(request:, config:, content_type: nil, env: {}, headers: {}, view_options: nil, sessions_enabled: false) # rubocop:disable Layout/LineLength, Metrics/ParameterLists
48
57
  super([], 200, headers.dup)
49
- set_header(Action::CONTENT_TYPE, content_type)
58
+ self.content_type = content_type if content_type
50
59
 
51
60
  @request = request
52
61
  @config = config
@@ -59,6 +68,10 @@ module Hanami
59
68
  @sending_file = false
60
69
  end
61
70
 
71
+ # Sets the response body.
72
+ #
73
+ # @param str [String] the body string
74
+ #
62
75
  # @since 2.0.0
63
76
  # @api public
64
77
  def body=(str)
@@ -73,32 +86,96 @@ module Hanami
73
86
  end
74
87
  end
75
88
 
76
- # @since 2.0.0
77
- # @api public
89
+ # This is NOT RELEASED with 2.0.0
90
+ #
91
+ # @api private
78
92
  def render(view, **options)
79
93
  self.body = view.(**view_options.(request, self), **exposures.merge(options)).to_str
80
94
  end
81
95
 
96
+ # Returns the format for the response.
97
+ #
98
+ # Returns nil if a format has not been assigned and also cannot be determined from the
99
+ # response's `#content_type`.
100
+ #
101
+ # @example
102
+ # response.format # => :json
103
+ #
104
+ # @return [Symbol, nil]
105
+ #
82
106
  # @since 2.0.0
83
107
  # @api public
84
- def format=(args)
85
- @format, content_type = *args
86
- content_type = Action::Mime.content_type_with_charset(content_type, charset)
87
- set_header("Content-Type", content_type)
108
+ def format
109
+ @format ||= Mime.detect_format(content_type, @config)
88
110
  end
89
111
 
112
+ # Sets the format and associated content type for the response.
113
+ #
114
+ # Either a format name (`:json`) or a content type string (`"application/json"`) may be given.
115
+ # In either case, the format or content type will be derived from the given value, and both
116
+ # will be set.
117
+ #
118
+ # @example Assigning via a format name symbol
119
+ # response.format = :json
120
+ # response.content_type # => "application/json"
121
+ # response.headers["Content-Type"] # => "application/json"
122
+ #
123
+ # @example Assigning via a content type string
124
+ # response.format = "application/json"
125
+ # response.format # => :json
126
+ # response.content_type # => "application/json"
127
+ #
128
+ # @param value [Symbol, String] the format name or content type
129
+ #
130
+ # @see Config#formats
131
+ #
132
+ # @since 2.0.0
133
+ # @api public
134
+ def format=(value)
135
+ format, content_type = Mime.detect_format_and_content_type(value, @config)
136
+
137
+ self.content_type = Mime.content_type_with_charset(content_type, charset)
138
+
139
+ @format = format
140
+ end
141
+
142
+ # Returns the exposure value for the given key.
143
+ #
144
+ # @param key [Object]
145
+ #
146
+ # @return [Object] the exposure value, if found
147
+ #
148
+ # @raise [KeyError] if the exposure was not found
149
+ #
90
150
  # @since 2.0.0
91
151
  # @api public
92
152
  def [](key)
93
153
  @exposures.fetch(key)
94
154
  end
95
155
 
156
+ # Sets an exposure value for the given key.
157
+ #
158
+ # @param key [Object]
159
+ # @param value [Object]
160
+ #
161
+ # @return [Object] the value
162
+ #
96
163
  # @since 2.0.0
97
164
  # @api public
98
165
  def []=(key, value)
99
166
  @exposures[key] = value
100
167
  end
101
168
 
169
+ # Returns the session for the response.
170
+ #
171
+ # This is the same session object as the {Request}.
172
+ #
173
+ # @return [Hash] the session object
174
+ #
175
+ # @raise [MissingSessionError] if sessions are not enabled
176
+ #
177
+ # @see Request#session
178
+ #
102
179
  # @since 2.0.0
103
180
  # @api public
104
181
  def session
@@ -109,6 +186,16 @@ module Hanami
109
186
  request.session
110
187
  end
111
188
 
189
+ # Returns the flash for the request.
190
+ #
191
+ # This is the same flash object as the {Request}.
192
+ #
193
+ # @return [Flash]
194
+ #
195
+ # @raise [MissingSessionError] if sessions are not enabled
196
+ #
197
+ # @see Request#flash
198
+ #
112
199
  # @since 2.0.0
113
200
  # @api public
114
201
  def flash
@@ -119,12 +206,21 @@ module Hanami
119
206
  request.flash
120
207
  end
121
208
 
209
+ # Returns the set of cookies to be included in the response.
210
+ #
211
+ # @return [CookieJar]
212
+ #
122
213
  # @since 2.0.0
123
214
  # @api public
124
215
  def cookies
125
216
  @cookies ||= CookieJar.new(env.dup, headers, @config.cookies)
126
217
  end
127
218
 
219
+ # Sets the response to redirect to the given URL and halts further handling.
220
+ #
221
+ # @param url [String]
222
+ # @param status [Integer] the HTTP status to use for the redirect
223
+ #
128
224
  # @since 2.0.0
129
225
  # @api public
130
226
  def redirect_to(url, status: 302)
@@ -134,6 +230,22 @@ module Hanami
134
230
  Halt.call(status)
135
231
  end
136
232
 
233
+ # Sends the file at the given path as the response, for any file within the configured
234
+ # `public_directory`.
235
+ #
236
+ # Handles the following aspects for file responses:
237
+ #
238
+ # - Setting `Content-Type` and `Content-Length` headers
239
+ # - File Not Found responses (returns a 404)
240
+ # - Conditional GET (via `If-Modified-Since` header)
241
+ # - Range requests (via `Range` header)
242
+ #
243
+ # @param path [String] the file path
244
+ #
245
+ # @return [void]
246
+ #
247
+ # @see Config#public_directory
248
+ #
137
249
  # @since 2.0.0
138
250
  # @api public
139
251
  def send_file(path)
@@ -142,6 +254,14 @@ module Hanami
142
254
  )
143
255
  end
144
256
 
257
+ # Send the file at the given path as the response, for a file anywhere in the file system.
258
+ #
259
+ # @see #send_file
260
+ #
261
+ # @param path [String, Pathname] path to the file to be sent
262
+ #
263
+ # @return [void]
264
+ #
145
265
  # @since 2.0.0
146
266
  # @api public
147
267
  def unsafe_send_file(path)
@@ -156,6 +276,37 @@ module Hanami
156
276
  )
157
277
  end
158
278
 
279
+ # Specifies the response freshness policy for HTTP caches using the `Cache-Control` header.
280
+ #
281
+ # Any number of non-value directives (`:public`, `:private`, `:no_cache`, `:no_store`,
282
+ # `:must_revalidate`, `:proxy_revalidate`) may be passed along with a Hash of value directives
283
+ # (`:max_age`, `:min_stale`, `:s_max_age`).
284
+ #
285
+ # See [RFC 2616 / 14.9](http://tools.ietf.org/html/rfc2616#section-14.9.1) for more on
286
+ # standard cache control directives.
287
+ #
288
+ # @example
289
+ # # Set Cache-Control directives
290
+ # response.cache_control :public, max_age: 900, s_maxage: 86400
291
+ #
292
+ # # Overwrite previous Cache-Control directives
293
+ # response.cache_control :private, :no_cache, :no_store
294
+ #
295
+ # response.get_header("Cache-Control") # => "private, no-store, max-age=900"
296
+ #
297
+ # @param values [Array<Symbol, Hash>] values to map to `Cache-Control` directives
298
+ # @option values [Symbol] :public
299
+ # @option values [Symbol] :private
300
+ # @option values [Symbol] :no_cache
301
+ # @option values [Symbol] :no_store
302
+ # @option values [Symbol] :must_validate
303
+ # @option values [Symbol] :proxy_revalidate
304
+ # @option values [Hash] :max_age
305
+ # @option values [Hash] :min_stale
306
+ # @option values [Hash] :s_max_age
307
+ #
308
+ # @return void
309
+ #
159
310
  # @since 2.0.0
160
311
  # @api public
161
312
  def cache_control(*values)
@@ -163,6 +314,28 @@ module Hanami
163
314
  headers.merge!(directives.headers)
164
315
  end
165
316
 
317
+ # Sets the `Expires` header and `Cache-Control`/`max-age` directive for the response.
318
+ #
319
+ # You can provide an integer number of seconds in the future, or a Time object indicating when
320
+ # the response should be considered "stale". The remaining arguments are passed to
321
+ # {#cache_control}.
322
+ #
323
+ # @example
324
+ # # Set Cache-Control directives and Expires
325
+ # response.expires 900, :public
326
+ #
327
+ # # Overwrite Cache-Control directives and Expires
328
+ # response.expires 300, :private, :no_cache, :no_store
329
+ #
330
+ # response.get_header("Expires") # => "Thu, 26 Jun 2014 12:00:00 GMT"
331
+ # response.get_header("Cache-Control") # => "private, no-cache, no-store max-age=300"
332
+ #
333
+ # @param amount [Integer, Time] number of seconds or point in time
334
+ # @param values [Array<Symbols>] values to map to `Cache-Control` directives via
335
+ # {#cache_control}
336
+ #
337
+ # @return void
338
+ #
166
339
  # @since 2.0.0
167
340
  # @api public
168
341
  def expires(amount, *values)
@@ -170,6 +343,26 @@ module Hanami
170
343
  headers.merge!(directives.headers)
171
344
  end
172
345
 
346
+ # Sets the `etag` and/or `last_modified` headers on the response and halts with a `304 Not
347
+ # Modified` response if the request is still fresh according to the `IfNoneMatch` and
348
+ # `IfModifiedSince` request headers.
349
+ #
350
+ # @example
351
+ # # Set etag header and halt 304 if request matches IF_NONE_MATCH header
352
+ # response.fresh etag: some_resource.updated_at.to_i
353
+ #
354
+ # # Set last_modified header and halt 304 if request matches IF_MODIFIED_SINCE
355
+ # response.fresh last_modified: some_resource.updated_at
356
+ #
357
+ # # Set etag and last_modified header and halt 304 if request matches IF_MODIFIED_SINCE and IF_NONE_MATCH
358
+ # response.fresh last_modified: some_resource.updated_at
359
+ #
360
+ # @param options [Hash]
361
+ # @option options [Integer] :etag for testing IfNoneMatch conditions
362
+ # @option options [Date] :last_modified for testing IfModifiedSince conditions
363
+ #
364
+ # @return void
365
+ #
173
366
  # @since 2.0.0
174
367
  # @api public
175
368
  def fresh(options)
@@ -183,7 +376,7 @@ module Hanami
183
376
  end
184
377
 
185
378
  # @since 2.0.0
186
- # @api public
379
+ # @api private
187
380
  def set_format(value) # rubocop:disable Naming/AccessorMethodName
188
381
  @format = value
189
382
  end
@@ -209,7 +402,7 @@ module Hanami
209
402
  alias_method :to_ary, :to_a
210
403
 
211
404
  # @since 2.0.0
212
- # @api public
405
+ # @api private
213
406
  def head?
214
407
  env[Action::REQUEST_METHOD] == Action::HEAD
215
408
  end
@@ -4,12 +4,17 @@ require "hanami/action/flash"
4
4
 
5
5
  module Hanami
6
6
  class Action
7
- # Session API
7
+ # Session support for actions.
8
8
  #
9
- # This module isn't included by default.
9
+ # Not included by default; you should include this module manually to enable session support.
10
+ # For actions within an Hanami app, this module will be included automatically if sessions are
11
+ # configured in the app config.
10
12
  #
13
+ # @api public
11
14
  # @since 0.1.0
12
15
  module Session
16
+ # @api private
17
+ # @since 0.1.0
13
18
  def self.included(base)
14
19
  base.class_eval do
15
20
  before { |req, _| req.id }
@@ -4,6 +4,12 @@ require "hanami/action/params"
4
4
 
5
5
  module Hanami
6
6
  class Action
7
+ # Support for validating params when calling actions.
8
+ #
9
+ # Included only when hanami-validations (and its dependencies) are bundled.
10
+ #
11
+ # @api private
12
+ # @since 0.1.0
7
13
  module Validatable
8
14
  # Defines the class name for anonymous params
9
15
  #
@@ -34,13 +40,10 @@ module Hanami
34
40
  # Once whitelisted, the params are available as an Hash with symbols
35
41
  # as keys.
36
42
  #
37
- #
38
- #
39
43
  # It accepts an anonymous block where all the params can be listed.
40
44
  # It internally creates an inner class which inherits from
41
45
  # Hanami::Action::Params.
42
46
  #
43
- #
44
47
  # Alternatively, it accepts an concrete class that should inherit from
45
48
  # Hanami::Action::Params.
46
49
  #
@@ -49,8 +52,6 @@ module Hanami
49
52
  #
50
53
  # @return void
51
54
  #
52
- # @since 0.3.0
53
- #
54
55
  # @see Hanami::Action::Params
55
56
  # @see https://guides.hanamirb.org//validations/overview
56
57
  #
@@ -93,6 +94,9 @@ module Hanami
93
94
  # req.params[:admin] # => nil
94
95
  # end
95
96
  # end
97
+ #
98
+ # @since 0.3.0
99
+ # @api public
96
100
  def params(klass = nil, &blk)
97
101
  if klass.nil?
98
102
  klass = const_set(PARAMS_CLASS_NAME, Class.new(Params))
data/lib/hanami/action.rb CHANGED
@@ -24,7 +24,7 @@ require_relative "action/mime"
24
24
  require_relative "action/rack/file"
25
25
  require_relative "action/request"
26
26
  require_relative "action/response"
27
- require_relative "action/error"
27
+ require_relative "action/errors"
28
28
 
29
29
  module Hanami
30
30
  # An HTTP endpoint
@@ -126,71 +126,72 @@ module Hanami
126
126
  #
127
127
  # @raise [NoMethodError]
128
128
  #
129
- # @api private
129
+ # @api public
130
130
  # @since 2.0.0
131
131
  def self.params(_klass = nil)
132
132
  raise NoMethodError,
133
133
  "To use `params`, please add 'hanami/validations' gem to your Gemfile"
134
134
  end
135
135
 
136
- # Define a callback for an Action.
137
- # The callback will be executed **before** the action is called, in the
138
- # order they are added.
136
+ # @overload self.append_before(*callbacks, &block)
137
+ # Define a callback for an Action.
138
+ # The callback will be executed **before** the action is called, in the
139
+ # order they are added.
139
140
  #
140
- # @param callbacks [Symbol, Array<Symbol>] a single or multiple symbol(s)
141
- # each of them is representing a name of a method available in the
142
- # context of the Action.
141
+ # @param callbacks [Symbol, Array<Symbol>] a single or multiple symbol(s)
142
+ # each of them is representing a name of a method available in the
143
+ # context of the Action.
143
144
  #
144
- # @param blk [Proc] an anonymous function to be executed
145
+ # @param blk [Proc] an anonymous function to be executed
145
146
  #
146
- # @return [void]
147
+ # @return [void]
147
148
  #
148
- # @since 0.3.2
149
+ # @since 0.3.2
149
150
  #
150
- # @see Hanami::Action::Callbacks::ClassMethods#append_after
151
+ # @see Hanami::Action::Callbacks::ClassMethods#append_after
151
152
  #
152
- # @example Method names (symbols)
153
- # require "hanami/controller"
153
+ # @example Method names (symbols)
154
+ # require "hanami/controller"
154
155
  #
155
- # class Show < Hanami::Action
156
- # before :authenticate, :set_article
156
+ # class Show < Hanami::Action
157
+ # before :authenticate, :set_article
157
158
  #
158
- # def handle(req, res)
159
- # end
159
+ # def handle(req, res)
160
+ # end
160
161
  #
161
- # private
162
- # def authenticate
163
- # # ...
164
- # end
162
+ # private
163
+ # def authenticate
164
+ # # ...
165
+ # end
165
166
  #
166
- # # `params` in the method signature is optional
167
- # def set_article(params)
168
- # @article = Article.find params[:id]
167
+ # # `params` in the method signature is optional
168
+ # def set_article(params)
169
+ # @article = Article.find params[:id]
170
+ # end
169
171
  # end
170
- # end
171
172
  #
172
- # # The order of execution will be:
173
- # #
174
- # # 1. #authenticate
175
- # # 2. #set_article
176
- # # 3. #call
173
+ # # The order of execution will be:
174
+ # #
175
+ # # 1. #authenticate
176
+ # # 2. #set_article
177
+ # # 3. #call
177
178
  #
178
- # @example Anonymous functions (Procs)
179
- # require "hanami/controller"
179
+ # @example Anonymous functions (Procs)
180
+ # require "hanami/controller"
180
181
  #
181
- # class Show < Hanami::Action
182
- # before { ... } # 1 do some authentication stuff
183
- # before {|req, res| @article = Article.find params[:id] } # 2
182
+ # class Show < Hanami::Action
183
+ # before { ... } # 1 do some authentication stuff
184
+ # before {|req, res| @article = Article.find params[:id] } # 2
184
185
  #
185
- # def handle(req, res)
186
+ # def handle(req, res)
187
+ # end
186
188
  # end
187
- # end
188
189
  #
189
- # # The order of execution will be:
190
- # #
191
- # # 1. authentication
192
- # # 2. set the article
193
- # # 3. `#handle`
190
+ # # The order of execution will be:
191
+ # #
192
+ # # 1. authentication
193
+ # # 2. set the article
194
+ # # 3. `#handle`
194
195
  def self.append_before(...)
195
196
  config.before_callbacks.append(...)
196
197
  end
@@ -200,21 +201,22 @@ module Hanami
200
201
  alias_method :before, :append_before
201
202
  end
202
203
 
203
- # Define a callback for an Action.
204
- # The callback will be executed **after** the action is called, in the
205
- # order they are added.
204
+ # @overload self.append_after(*callbacks, &block)
205
+ # Define a callback for an Action.
206
+ # The callback will be executed **after** the action is called, in the
207
+ # order they are added.
206
208
  #
207
- # @param callbacks [Symbol, Array<Symbol>] a single or multiple symbol(s)
208
- # each of them is representing a name of a method available in the
209
- # context of the Action.
209
+ # @param callbacks [Symbol, Array<Symbol>] a single or multiple symbol(s)
210
+ # each of them is representing a name of a method available in the
211
+ # context of the Action.
210
212
  #
211
- # @param blk [Proc] an anonymous function to be executed
213
+ # @param blk [Proc] an anonymous function to be executed
212
214
  #
213
- # @return [void]
215
+ # @return [void]
214
216
  #
215
- # @since 0.3.2
217
+ # @since 0.3.2
216
218
  #
217
- # @see Hanami::Action::Callbacks::ClassMethods#append_before
219
+ # @see Hanami::Action::Callbacks::ClassMethods#append_before
218
220
  def self.append_after(...)
219
221
  config.after_callbacks.append(...)
220
222
  end
@@ -224,40 +226,42 @@ module Hanami
224
226
  alias_method :after, :append_after
225
227
  end
226
228
 
227
- # Define a callback for an Action.
228
- # The callback will be executed **before** the action is called.
229
- # It will add the callback at the beginning of the callbacks' chain.
229
+ # @overload self.prepend_before(*callbacks, &block)
230
+ # Define a callback for an Action.
231
+ # The callback will be executed **before** the action is called.
232
+ # It will add the callback at the beginning of the callbacks' chain.
230
233
  #
231
- # @param callbacks [Symbol, Array<Symbol>] a single or multiple symbol(s)
232
- # each of them is representing a name of a method available in the
233
- # context of the Action.
234
+ # @param callbacks [Symbol, Array<Symbol>] a single or multiple symbol(s)
235
+ # each of them is representing a name of a method available in the
236
+ # context of the Action.
234
237
  #
235
- # @param blk [Proc] an anonymous function to be executed
238
+ # @param blk [Proc] an anonymous function to be executed
236
239
  #
237
- # @return [void]
240
+ # @return [void]
238
241
  #
239
- # @since 0.3.2
242
+ # @since 0.3.2
240
243
  #
241
- # @see Hanami::Action::Callbacks::ClassMethods#prepend_after
244
+ # @see Hanami::Action::Callbacks::ClassMethods#prepend_after
242
245
  def self.prepend_before(...)
243
246
  config.before_callbacks.prepend(...)
244
247
  end
245
248
 
246
- # Define a callback for an Action.
247
- # The callback will be executed **after** the action is called.
248
- # It will add the callback at the beginning of the callbacks' chain.
249
+ # @overload self.prepend_after(*callbacks, &block)
250
+ # Define a callback for an Action.
251
+ # The callback will be executed **after** the action is called.
252
+ # It will add the callback at the beginning of the callbacks' chain.
249
253
  #
250
- # @param callbacks [Symbol, Array<Symbol>] a single or multiple symbol(s)
251
- # each of them is representing a name of a method available in the
252
- # context of the Action.
254
+ # @param callbacks [Symbol, Array<Symbol>] a single or multiple symbol(s)
255
+ # each of them is representing a name of a method available in the
256
+ # context of the Action.
253
257
  #
254
- # @param blk [Proc] an anonymous function to be executed
258
+ # @param blk [Proc] an anonymous function to be executed
255
259
  #
256
- # @return [void]
260
+ # @return [void]
257
261
  #
258
- # @since 0.3.2
262
+ # @since 0.3.2
259
263
  #
260
- # @see Hanami::Action::Callbacks::ClassMethods#prepend_before
264
+ # @see Hanami::Action::Callbacks::ClassMethods#prepend_before
261
265
  def self.prepend_after(...)
262
266
  config.after_callbacks.prepend(...)
263
267
  end
@@ -266,7 +270,7 @@ module Hanami
266
270
  #
267
271
  # @param formats[Array<Symbol>] one or more symbols representing mime type(s)
268
272
  #
269
- # @raise [Hanami::Controller::UnknownFormatError] if the symbol cannot
273
+ # @raise [Hanami::Action::UnknownFormatError] if the symbol cannot
270
274
  # be converted into a mime type
271
275
  #
272
276
  # @since 0.1.0
@@ -586,20 +590,6 @@ module Hanami
586
590
  res.body = Response::EMPTY_BODY
587
591
  end
588
592
 
589
- # @since 2.0.0
590
- # @api private
591
- def format(value)
592
- case value
593
- when Symbol
594
- format = Utils::Kernel.Symbol(value)
595
- [format, Action::Mime.format_to_mime_type(format, config)]
596
- when String
597
- [Action::Mime.detect_format(value, config), value]
598
- else
599
- raise Hanami::Controller::UnknownFormatError.new(value)
600
- end
601
- end
602
-
603
593
  # Finalize the response
604
594
  #
605
595
  # Prepare the data before the response will be returned to the webserver
@@ -2,9 +2,7 @@
2
2
 
3
3
  module Hanami
4
4
  module Controller
5
- # Defines the version
6
- #
7
- # @since 0.1.0
8
- VERSION = "2.0.0.beta4"
5
+ # @api public
6
+ VERSION = "2.0.0.rc1"
9
7
  end
10
8
  end
@@ -2,7 +2,6 @@
2
2
 
3
3
  require "hanami/action"
4
4
  require "hanami/controller/version"
5
- require "hanami/controller/error"
6
5
 
7
6
  # Hanami
8
7
  #
@@ -27,20 +26,5 @@ module Hanami
27
26
  # end
28
27
  # end
29
28
  module Controller
30
- # Unknown format error
31
- #
32
- # This error is raised when a action sets a format that it isn't recognized
33
- # both by `Hanami::Action::Configuration` and the list of Rack mime types
34
- #
35
- # @since 0.2.0
36
- #
37
- # @see Hanami::Action::Mime#format=
38
- class UnknownFormatError < Hanami::Controller::Error
39
- # @since 0.2.0
40
- # @api private
41
- def initialize(format)
42
- super("Cannot find a corresponding Mime type for '#{format}'. Please configure it with Hanami::Controller::Configuration#format.") # rubocop:disable Layout/LineLength
43
- end
44
- end
45
29
  end
46
30
  end