exception_handler 0.7.7.0 → 0.8.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +13 -3
  3. data/.rspec +3 -0
  4. data/.travis.yml +4 -2
  5. data/Gemfile +3 -0
  6. data/README.md +330 -124
  7. data/app/assets/stylesheets/exception_handler.css.erb +5 -0
  8. data/app/assets/stylesheets/styles/_base.css.erb +1 -8
  9. data/app/assets/stylesheets/styles/_exception.css.erb +2 -1
  10. data/app/controllers/exception_handler/exceptions_controller.rb +10 -3
  11. data/app/models/exception_handler/exception.rb +21 -20
  12. data/app/views/exception_handler/exceptions/show.html.erb +1 -1
  13. data/app/views/layouts/exception.html.erb +5 -0
  14. data/app/views/layouts/mailer.html.erb +5 -0
  15. data/app/views/layouts/mailer.text.erb +1 -0
  16. data/config/locales/exception_handler.en.yml +1 -1
  17. data/config/routes.rb +42 -0
  18. data/exception_handler.gemspec +9 -8
  19. data/lib/exception_handler.rb +1 -0
  20. data/lib/exception_handler/config.rb +109 -40
  21. data/lib/exception_handler/engine.rb +11 -3
  22. data/lib/exception_handler/version.rb +2 -2
  23. data/spec/controllers/controller_spec.rb +107 -0
  24. data/spec/dummy/.rspec +1 -0
  25. data/spec/dummy/.ruby-version +1 -0
  26. data/spec/dummy/Rakefile +6 -0
  27. data/spec/dummy/app/assets/config/manifest.js +3 -0
  28. data/spec/dummy/app/assets/images/.keep +0 -0
  29. data/spec/dummy/app/assets/javascripts/application.js +15 -0
  30. data/spec/dummy/app/assets/javascripts/cable.js +13 -0
  31. data/spec/dummy/app/assets/javascripts/channels/.keep +0 -0
  32. data/spec/dummy/app/assets/stylesheets/application.css +15 -0
  33. data/spec/dummy/app/channels/application_cable/channel.rb +4 -0
  34. data/spec/dummy/app/channels/application_cable/connection.rb +4 -0
  35. data/spec/dummy/app/controllers/application_controller.rb +2 -0
  36. data/spec/dummy/app/controllers/concerns/.keep +0 -0
  37. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  38. data/spec/dummy/app/jobs/application_job.rb +2 -0
  39. data/spec/dummy/app/mailers/application_mailer.rb +4 -0
  40. data/spec/dummy/app/models/application_record.rb +3 -0
  41. data/spec/dummy/app/models/concerns/.keep +0 -0
  42. data/spec/dummy/app/views/layouts/application.html.erb +15 -0
  43. data/spec/dummy/app/views/layouts/mailer.html.erb +13 -0
  44. data/spec/dummy/app/views/layouts/mailer.text.erb +1 -0
  45. data/spec/dummy/bin/bundle +3 -0
  46. data/spec/dummy/bin/rails +4 -0
  47. data/spec/dummy/bin/rake +4 -0
  48. data/spec/dummy/bin/setup +36 -0
  49. data/spec/dummy/bin/update +31 -0
  50. data/spec/dummy/bin/yarn +11 -0
  51. data/spec/dummy/config.ru +5 -0
  52. data/spec/dummy/config/application.rb +18 -0
  53. data/spec/dummy/config/boot.rb +5 -0
  54. data/spec/dummy/config/cable.yml +10 -0
  55. data/spec/dummy/config/database.yml +25 -0
  56. data/spec/dummy/config/environment.rb +5 -0
  57. data/spec/dummy/config/environments/development.rb +61 -0
  58. data/spec/dummy/config/environments/production.rb +94 -0
  59. data/spec/dummy/config/environments/test.rb +46 -0
  60. data/spec/dummy/config/initializers/application_controller_renderer.rb +8 -0
  61. data/spec/dummy/config/initializers/assets.rb +14 -0
  62. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  63. data/spec/dummy/config/initializers/content_security_policy.rb +25 -0
  64. data/spec/dummy/config/initializers/cookies_serializer.rb +5 -0
  65. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  66. data/spec/dummy/config/initializers/inflections.rb +16 -0
  67. data/spec/dummy/config/initializers/mime_types.rb +4 -0
  68. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  69. data/spec/dummy/config/locales/en.yml +33 -0
  70. data/spec/dummy/config/puma.rb +34 -0
  71. data/spec/dummy/config/routes.rb +3 -0
  72. data/spec/dummy/config/storage.yml +34 -0
  73. data/spec/dummy/lib/assets/.keep +0 -0
  74. data/spec/dummy/log/.keep +0 -0
  75. data/spec/dummy/package.json +5 -0
  76. data/spec/dummy/public/404.html +67 -0
  77. data/spec/dummy/public/422.html +67 -0
  78. data/spec/dummy/public/500.html +66 -0
  79. data/spec/dummy/public/apple-touch-icon-precomposed.png +0 -0
  80. data/spec/dummy/public/apple-touch-icon.png +0 -0
  81. data/spec/dummy/public/favicon.ico +0 -0
  82. data/spec/dummy/spec/rails_helper.rb +57 -0
  83. data/spec/dummy/spec/spec_helper.rb +100 -0
  84. data/spec/dummy/storage/.keep +0 -0
  85. data/spec/features/asset_spec.rb +61 -0
  86. data/spec/features/config_spec.rb +51 -0
  87. data/spec/features/engine_spec.rb +180 -0
  88. data/spec/routing/routing_spec.rb +85 -0
  89. data/spec/spec_helper.rb +93 -0
  90. data/spec/views/views_spec.rb +29 -0
  91. metadata +79 -6
  92. data/app/assets/images/exception_handler/bg.jpg +0 -0
  93. data/app/assets/images/exception_handler/bg_overlay.png +0 -0
@@ -15,4 +15,9 @@
15
15
  */
16
16
  /* ---------------------------------------------------- */
17
17
  /* ---------------------------------------------------- */
18
+ /*
19
+ *= link_tree ../images
20
+ */
21
+ /* ---------------------------------------------------- */
22
+ /* ---------------------------------------------------- */
18
23
  /* ---------------------------------------------------- */
@@ -4,19 +4,12 @@
4
4
  /* ---------------------------------------------------- */
5
5
  /* ---------------------------------------------------- */
6
6
 
7
- /*
8
- *= link_tree ../../images
9
- */
10
-
11
- /* ---------------------------------------------------- */
12
- /* ---------------------------------------------------- */
13
-
14
7
  * { margin: 0; }
15
8
  html, body { height: 100%; }
16
9
  html {
17
10
  height: 100%;
18
11
  color: #fff;
19
- background: #010008 url(<%= asset_url("exception_handler/bg.jpg") %>) top left no-repeat;
12
+ background: #121212;
20
13
  background-size: 100% 100%;
21
14
  box-sizing: border-box;
22
15
  }
@@ -53,7 +53,8 @@
53
53
  border-color: rgba(255,255,255,0.09);
54
54
  border-style: solid
55
55
  }
56
- .exception:hover { cursor: pointer; }
56
+ .exception:hover { cursor: pointer; }
57
+ .exception:hover:after { text-decoration: underline; }
57
58
 
58
59
  .exception span:before {
59
60
  display: block;
@@ -36,9 +36,11 @@ module ExceptionHandler
36
36
  layout :layout
37
37
 
38
38
  ####################
39
- # Action #
39
+ # Actions #
40
40
  ####################
41
41
 
42
+ # => General Show Functionality
43
+ # => Introduced new "action" config option in 0.8.0.0
42
44
  def show
43
45
  respond_with @exception, status: @exception.status
44
46
  end
@@ -48,8 +50,13 @@ module ExceptionHandler
48
50
 
49
51
  private
50
52
 
51
- def layout
52
- ExceptionHandler.config.layouts[@exception.status]
53
+ # => Pulls from Exception class
54
+ # => Spanner in the works is nil
55
+ # => .present? validates against empty strings (IE a string is present)
56
+ # => .nil? validates to see if the returned data is "nil"
57
+ # => nil required to facilitate inheritance of the layout w/ ApplicationController
58
+ def layout option = ExceptionHandler.config.options(@exception.status, :layout)
59
+ (option.present? || option.nil?) ? option : 'exception'
53
60
  end
54
61
 
55
62
  ##################################
@@ -10,20 +10,13 @@ module ExceptionHandler
10
10
  # => Attributes
11
11
  # => Determine schema etc
12
12
  ATTRS = %i(class_name status message trace target referrer params user_agent)
13
-
14
- # => Exceptions to be rescued by ExceptionHandler
15
- EXCEPTIONS_TO_BE_RESCUED = [ActionController::RoutingError, AbstractController::ActionNotFound].tap do |list|
16
- list << ActiveRecord::RecordNotFound if defined?(ActiveRecord)
17
- list << Mongoid::Errors::DocumentNotFound if defined?(Mongoid)
18
- end
19
13
 
20
14
  ############################################################
21
15
  ############################################################
22
16
 
23
17
  # => Class (inheritance dependent on whether db option is available)
24
- self::Exception = Class.new(
25
- (ExceptionHandler.config.try(:db) && defined?(ActiveRecord)) ? ActiveRecord::Base : Object
26
- ) do
18
+ self::Exception =
19
+ Class.new( (ExceptionHandler.config.try(:db) && defined?(ActiveRecord)) ? ActiveRecord::Base : Object ) do
27
20
 
28
21
  # => Include individual elements
29
22
  # => Only required if no db present (no ActiveRecord)
@@ -97,15 +90,14 @@ module ExceptionHandler
97
90
  # => Email
98
91
  # => after_initialize invoked after .new method called
99
92
  # => Should have been after_create but user may not save
100
- after_initialize Proc.new { |e| ExceptionHandler::ExceptionMailer.new_exception(e).deliver } if ExceptionHandler.config.try(:email).try(:is_a?, String)
93
+ after_initialize -> (e) { ExceptionHandler::ExceptionMailer.new_exception(e).deliver }, if: :email? # => see bottom of file
101
94
 
102
95
  # => Attributes
103
96
  attr_accessor :request, :klass, :exception, :description
104
97
  attr_accessor *ATTRS unless ExceptionHandler.config.try(:db)
105
98
 
106
99
  # => Validations
107
- validates :klass, exclusion: { in: EXCEPTIONS_TO_BE_RESCUED, message: "%{value}" }, if: -> { referer.blank? } # => might need full Proc syntax
108
- validates :user_agent, format: { without: Regexp.new( BOTS.join("|"), Regexp::IGNORECASE ) }
100
+ validates :user_agent, format: { without: Regexp.new( BOTS.join("|"), Regexp::IGNORECASE ) }
109
101
 
110
102
  ##################################
111
103
  ##################################
@@ -114,21 +106,22 @@ module ExceptionHandler
114
106
  # Virtual
115
107
  ####################################
116
108
 
109
+ # => Exception (virtual)
110
+ # => Basis on which all the class is built
111
+ def exception
112
+ request.env['action_dispatch.exception']
113
+ end
114
+
117
115
  # => Klass
118
116
  # => Used for validation (needs to be cleaned up in 0.7.0)
119
117
  def klass
120
118
  exception.class
121
119
  end
122
120
 
123
- # => Exception (virtual)
124
- def exception
125
- request.env['action_dispatch.exception']
126
- end
127
-
128
121
  # => Description
129
122
  def description
130
123
  I18n.with_options scope: [:exception_handler], message: message, status: status do |i18n|
131
- i18n.t response, default: Rack::Utils::HTTP_STATUS_CODES[status] || status
124
+ i18n.t response, default: Rack::Utils::HTTP_STATUS_CODES[status]
132
125
  end
133
126
  end
134
127
 
@@ -143,7 +136,7 @@ module ExceptionHandler
143
136
 
144
137
  # => Message
145
138
  def message
146
- exception.message
139
+ exception ? exception.message : Rack::Utils::HTTP_STATUS_CODES[status]
147
140
  end
148
141
 
149
142
  # => Trace
@@ -181,7 +174,7 @@ module ExceptionHandler
181
174
 
182
175
  # => Status code (404, 500 etc)
183
176
  def status
184
- ActionDispatch::ExceptionWrapper.new(request.env, exception).status_code
177
+ exception ? ActionDispatch::ExceptionWrapper.new(request.env, exception).try(:status_code) : request.env["PATH_INFO"][1..-1].to_i
185
178
  end
186
179
 
187
180
  # => Server Response ("Not Found" etc)
@@ -192,6 +185,14 @@ module ExceptionHandler
192
185
  ##################################
193
186
  ##################################
194
187
 
188
+ private
189
+
190
+ # => Email
191
+ # => should be on the same line as after_initialize but too long
192
+ def email?
193
+ ExceptionHandler.config.try(:email).try(:is_a?, String) && ExceptionHandler.config.options(status, :notification) != false
194
+ end
195
+
195
196
  end
196
197
  end
197
198
 
@@ -1,3 +1,3 @@
1
- <%= content_tag :div, class: "exception", data: { status: @exception.status, response: @exception.response.to_s.humanize, rails: Rails.version }, onclick: ("location.href=\"#{root_url}\";" if @exception.status == "500" && Rails.application.routes.recognize_path("/")), title: ("Return Home" if @exception.status == "500" && Rails.application.routes.recognize_path("/")) do %>
1
+ <%= content_tag :div, class: "exception", data: { status: @exception.status, response: @exception.response.to_s.humanize, rails: Rails.version }, onclick: ("location.href=\"#{root_url}\";" if @exception.status.to_s.first == "5" && Rails.application.routes.recognize_path("/")) do %>
2
2
  <%= content_tag :span, @exception.description.html_safe %>
3
3
  <% end %>
@@ -9,6 +9,10 @@
9
9
  <%= stylesheet_link_tag :exception_handler %>
10
10
  <%= favicon_link_tag "exception_handler/favicon.ico" %>
11
11
 
12
+ <% if x = ExceptionHandler.config.options(@exception.status) %>
13
+ <style>body { background: url("<%= asset_path x %>") center center no-repeat !important; background-size: cover !important; }</style>
14
+ <% end %>
15
+
12
16
  <!-- Auth -->
13
17
  <%= csrf_meta_tags %>
14
18
  </head>
@@ -24,4 +28,5 @@
24
28
  <% end %>
25
29
  <% end %>
26
30
  <% end %>
31
+
27
32
  </html>
@@ -0,0 +1,5 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head><meta content="text/html; charset=utf-8" http-equiv="Content-Type" /></head>
4
+ <body><%= yield %></body>
5
+ </html>
@@ -0,0 +1 @@
1
+ <%= yield %>
@@ -22,7 +22,7 @@
22
22
 
23
23
  en:
24
24
  exception_handler:
25
- internal_server_error: "<strong>%{status} Error</strong> %{message} <p>Return home</p>"
25
+ internal_server_error: "<strong>%{status} Error</strong> %{message}"
26
26
 
27
27
  #######################################################################################
28
28
  #######################################################################################
@@ -0,0 +1,42 @@
1
+ ########################################
2
+ ########################################
3
+ ## _____ _ ##
4
+ ## | ___ \ | | ##
5
+ ## | |_/ /___ _ _| |_ ___ ___ ##
6
+ ## | // _ \| | | | __/ _ \/ __| ##
7
+ ## | |\ \ (_) | |_| | || __/\__ \ ##
8
+ ## \_| \_\___/ \__,_|\__\___||___/ ##
9
+ ## ##
10
+ ########################################
11
+ ########################################
12
+
13
+ ## Good resource
14
+ ## https://gist.github.com/maxivak/5d428ade54828836e6b6#merge-engine-and-app-routes
15
+
16
+ ########################################
17
+ ########################################
18
+
19
+ ## Routes ##
20
+ Rails.application.routes.draw do
21
+
22
+ ########################################
23
+ ########################################
24
+
25
+ # => ExceptionHandler
26
+ # => Used to provide error page examples in "dev" mode
27
+ if Object.const_defined?('ExceptionHandler') && ExceptionHandler.config.try(:dev)
28
+
29
+ # => Items
30
+ Rack::Utils::SYMBOL_TO_STATUS_CODE.select{ |key, value| value.to_s.match('\b(?:4[0-9]{2}|5[0-9]{2}|599)\b') }.each do |code, status|
31
+ get status.to_s, to: 'exception_handler/exceptions#show', as: code, code: code
32
+ end
33
+
34
+ end
35
+
36
+ ########################################
37
+ ########################################
38
+
39
+ end
40
+
41
+ ########################################
42
+ ########################################
@@ -11,16 +11,17 @@ require_relative 'lib/exception_handler/version'
11
11
  Gem::Specification.new do |s|
12
12
 
13
13
  ## General ##
14
- s.name = "exception_handler"
15
- s.authors = ["R.Peck"]
16
- s.email = ["rpeck@fl.co.uk"]
17
- s.version = ExceptionHandler::VERSION::STRING
18
- s.platform = Gem::Platform::RUBY
14
+ s.name = "exception_handler"
15
+ s.authors = ["R.Peck"]
16
+ s.email = ["rpeck@fl.co.uk"]
17
+ s.version = ExceptionHandler::VERSION::STRING
18
+ s.platform = Gem::Platform::RUBY
19
19
 
20
20
  ## Details ##
21
- s.summary = %q{Rails gem to show custom error pages in production. Also logs errors in db & sends notification emails}
22
- s.description = %q{Rails gem to create custom error pages. Captures exceptions using "exception_app" callback, routing to "Exception" controller, rendering the view as required.}
23
- s.homepage = "https://github.com/richpeck/exception_handler"
21
+ s.summary = %q{Rails gem to show custom error pages in production. Also logs errors in db & sends notification emails}
22
+ s.description = %q{Rails gem to create custom error pages. Captures exceptions using "exception_app" callback, routing to "Exception" controller, rendering the view as required.}
23
+ s.post_install_message = %q{ExceptionHandler 0.8.0.0 → New "config" (config.exception_handler = {exceptions: {layout: 'x', notification: true, action: {redirect_to root_path} }} ). https://www.github.com/richpeck/exception_handler#config for more info. }
24
+ s.homepage = "https://github.com/richpeck/exception_handler"
24
25
 
25
26
  ## License ##
26
27
  s.license = "MIT"
@@ -37,6 +37,7 @@ module ExceptionHandler
37
37
  ##############################
38
38
  ##############################
39
39
 
40
+
40
41
  end
41
42
 
42
43
  #########################################################
@@ -7,7 +7,7 @@
7
7
  ## | \__/\ (_) | | | | | | | (_| | ##
8
8
  ## \____/\___/|_| |_|_| |_|\__, | ##
9
9
  ## __/ | ##
10
- ## |___/ ##
10
+ ## |___/ ##
11
11
  ###########################################
12
12
  ###########################################
13
13
 
@@ -26,9 +26,10 @@ module ExceptionHandler
26
26
  # => ExceptionHandler.config.db
27
27
  # => ExceptionHandler.config.email
28
28
  # => ExceptionHandler.config.social
29
- # => ExceptionHandler.config.layouts
29
+ # => ExceptionHandler.config.layouts -> will need to be deprecated
30
+ # => ExceptionHandler.config.exceptions
30
31
  # => ExceptionHandler.config.custom_exceptions
31
- attr_accessor :dev, :db, :email, :social, :layouts, :custom_exceptions
32
+ attr_accessor :dev, :db, :email, :social, :layouts, :exceptions, :custom_exceptions
32
33
 
33
34
  ###########################################
34
35
  ###########################################
@@ -39,51 +40,96 @@ module ExceptionHandler
39
40
  # => Has to be "errors" because "exceptions" is a reserved word
40
41
  TABLE = :errors
41
42
 
43
+ ###########################################
44
+ ###########################################
45
+
42
46
  # => Social URLs
43
47
  # => Extracted from "social" block
44
- SOCIAL = {
45
- facebook: "https://facebook.com",
46
- twitter: "https://twitter.com",
47
- youtube: "https://youtube.com/user",
48
- linkedin: "https://linkedin.com/company",
49
- fusion: "https://frontlinefusion.com"
50
- }
48
+ SOCIAL =
49
+ ActiveSupport::HashWithIndifferentAccess.new({
50
+ facebook: "https://www.facebook.com",
51
+ twitter: "https://www.twitter.com",
52
+ youtube: "https://www.youtube.com/user",
53
+ linkedin: "https://www.linkedin.com/company",
54
+ fusion: "https://www.frontlinefusion.com"
55
+ })
51
56
 
52
57
  ###########################################
53
58
  ###########################################
54
59
 
55
60
  # => Defaults
56
61
  # => http://stackoverflow.com/a/8917301/1143732
57
- DEFAULTS = {
58
- dev: nil, # => defaults to "false" for dev mode
59
- db: nil, # => defaults to :errors if true, else use "table_name" / :table_name
60
- email: nil, # => requires string email and ActionMailer
61
- social: {
62
- facebook: nil,
63
- twitter: nil,
64
- youtube: nil,
65
- linkedin: nil,
66
- fusion: nil,
67
- },
68
- layouts: {
69
- # => nil inherits from ApplicationController
70
- # => 4xx errors should be nil
71
- # => 5xx errors should be "exception" but can be nil if explicitly defined
72
- 500 => "exception",
73
- 501 => "exception",
74
- 502 => "exception",
75
- 503 => "exception",
76
- 504 => "exception",
77
- 505 => "exception",
78
- 507 => "exception",
79
- 510 => "exception"
80
- }
81
- }
82
-
83
- ###########################################
84
- ###########################################
85
-
86
- # => Init
62
+ DEFAULTS =
63
+ ActiveSupport::HashWithIndifferentAccess.new({
64
+
65
+ # => General options
66
+ dev: nil, # => defaults to "false" for dev mode
67
+ db: nil, # => defaults to :errors if true, else use "table_name" / :table_name
68
+ email: nil, # => requires string email and ActionMailer
69
+
70
+ # => Used in "exception" layout
71
+ social: {
72
+ facebook: nil,
73
+ twitter: nil,
74
+ youtube: nil,
75
+ linkedin: nil,
76
+ fusion: nil,
77
+ },
78
+
79
+ # => Defaults for exceptions. Override with specific status codes
80
+ # => Please note these are all STRINGS
81
+ exceptions: {
82
+
83
+ # => 4xx/5xx base standard
84
+ # => :all provide block customization (overrides 4xx/5xx)
85
+ # => specific provides individual (overrides all)
86
+
87
+ # => 4xx Errors (resource not found)
88
+ # => https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#4xx_Client_errors
89
+ '4xx' => {
90
+ layout: nil
91
+ # notification: true #(this is for emails - it's true by default - only if you have email inputted)
92
+ # action: ____, (this is general)
93
+ # background: (can define custom background for exceptions layout if required)
94
+ },
95
+
96
+ # => 5xx Errors (server error)
97
+ # => https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#5xx_Server_errors
98
+ '5xx' => {
99
+ layout: 'exception'
100
+ # notification: true (this is for emails - it's true by default - only if you have email inputted)
101
+ # action: _____, (this is general)
102
+ # background: (can define custom background for exceptions layout if required)
103
+ }
104
+ },
105
+
106
+ # Deprecated
107
+ #layouts: {
108
+ # => nil inherits from ApplicationController
109
+ # => 4xx errors should be nil
110
+ # => 5xx errors should be "exception" but can be nil if explicitly defined
111
+ #500 => 'exception',
112
+ #501 => 'exception',
113
+ #502 => 'exception',
114
+ #503 => 'exception',
115
+ #504 => 'exception',
116
+ #505 => 'exception',
117
+ #507 => 'exception',
118
+ #510 => 'exception'
119
+ #},
120
+
121
+ # => If you want to map your own classes to HTTP errors
122
+ # => use this...
123
+ custom_exceptions: {
124
+ #'ActionController::RoutingError' => :not_found # => example
125
+ }
126
+
127
+ })
128
+
129
+ ###########################################
130
+ ###########################################
131
+
132
+ # => Constructor
87
133
  # => Merges DEFAULTS to values, creates instances vars (for attr_accessor)
88
134
  def initialize values
89
135
 
@@ -107,6 +153,29 @@ module ExceptionHandler
107
153
  @db == true ? TABLE : @db.try(:parameterize, separator: "_")
108
154
  end
109
155
 
156
+ ###########################################
157
+ ###########################################
158
+
159
+ # => Options
160
+ # => Requires argument
161
+ def options status, pluck=nil
162
+
163
+ # => Structure from old + new setup
164
+ # => 1. layouts => [500, '500']
165
+ # => 2. exceptions => [500, '500' 'all', '4xx'/'5xx']
166
+ { layouts: [status, status.to_s], # old + new
167
+ exceptions: [status, status.to_s, 'all', status.to_s.first + 'xx'] }.each do |key,array|
168
+
169
+ # => Array
170
+ # => https://stackoverflow.com/a/26877095/1143732
171
+ array.each do |specific|
172
+ item = self.send(key).try(:[], specific)
173
+ return (item.is_a?(Hash) ? ActiveSupport::HashWithIndifferentAccess.new(item)[pluck.try(:to_sym)] : item) if item.present? || (self.send(key).try(:has_key?, specific) && item.nil?) #if result exists and it has a value (including nil)
174
+ end
175
+
176
+ end
177
+ end
178
+
110
179
  ###########################################
111
180
  ###########################################
112
181
  ###########################################