Module: Wrangler::ControllerMethods

Defined in:
lib/wrangler.rb

Overview

module of instance methods to be added to the class including Wrangler only if the including class is a rails controller class


Instance Method Summary collapse

Instance Method Details

#get_view_path_for_exception(exception, status_code) ⇒ Object

select the appropriate view path for the exception/status code. see README or the code for the different attempts that are made to find a template.




135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
# File 'lib/wrangler.rb', line 135

def get_view_path_for_exception(exception, status_code)

  # maintenance note: this method has lots of RETURN statements, so be
  # a little careful, but basically, it returns as soon as it finds a
  # file match, so there shouldn't be any processing to perform after
  # a match is found. any such logic does not belong in this method

  if exception.is_a?(Class)
    exception_class = exception
  else
    exception_class = exception.class
  end

  # Note: this converts "::" to "/", so views need to be nested under
  # exceptions' modules if appropriate
  exception_filename_root = exception_class.name.underscore

  template_mappings = nil
  case request.format
  when /html/
    response_format = 'html'
    template_mappings = Wrangler::ExceptionHandler.config[:error_class_html_templates]
  when /js/
    response_format = 'js'
    template_mappings = Wrangler::ExceptionHandler.config[:error_class_js_templates]
  when /xml/
    'xml'
  end
  format_extension_pattern = ".#{response_format || ''}*"

  if template_mappings
    # search for direct mapping from exception name to error template

    if template_mappings[exception_class.name]
      error_file = template_mappings[exception_class.name]

      return error_file if File.exists?(error_file)

      log_error("Found mapping from exception class " +
                "#{exception_class.name} to error file '#{error_file}', " +
                "but error file was not found")
    end

    # search for mapping from an ancestor class to error template
    ancestor_class =
      Wrangler::class_has_ancestor?(exception_class.superclass,
                                   template_mappings.keys)

    if ancestor_class
      error_file = template_mappings[ancestor_class.name]

      return error_file if File.exists?(error_file)

      log_error("Found mapping from ancestor exception class " +
                "#{ancestor_class.name} to error file '#{error_file}', " +
                "but error file was not found")
    end

  end # end if template_mappings

  # search for a file named after the exception in one of the search dirs

  search_paths = [ Wrangler::ExceptionHandler::config[:error_template_dir],
                   File.join(RAILS_ROOT, 'public'),
                   File.join(WRANGLER_ROOT, 'rails', 'app', 'views', 'wrangler')
                 ]

  # find files in specified directory like 'exception_class_name.format', e.g.
  # standard_error.html or standard_error.js.erb
  exception_pattern = "#{exception_filename_root}#{format_extension_pattern}"
  file_path = find_file_matching_pattern(search_paths, exception_pattern)

  return file_path if file_path

  # search for a file named after the error status code in search dirs

  status_code_pattern = "#{status_code}#{format_extension_pattern}"
  file_path = find_file_matching_pattern(search_paths, status_code_pattern)

  return file_path if file_path

  # search for a file named after ancestors of the exception in search dirs

  # look through exception's entire ancenstry to see if there's a matching
  # template in the search directories
  curr_ancestor = exception_class.superclass
  while curr_ancestor
    # find files in specified directory like 'exception_class_name.format', e.g.
    # standard_error.html or standard_error.js.erb
    exception_pattern =
      "#{curr_ancestor.name.underscore}#{format_extension_pattern}"
    file_path = find_file_matching_pattern(search_paths, exception_pattern)

    return file_path if file_path

    curr_ancestor = curr_ancestor.superclass
  end

  # didn't find anything
  return nil
end

#render_error_template(exception, status_code) ⇒ Object

select the proper file to render and do so. if the usual places don’t turn up an appropriate template (see README), then fall back on an app-specific default error page or the ultimate back up gem default page.




98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/wrangler.rb', line 98

def render_error_template(exception, status_code)
  file_path = get_view_path_for_exception(exception, status_code)
  
  # if that didn't work, fall back on configured app-specific default
  if file_path.blank? || !File.exists?(file_path)
    file_path = Wrangler::Exception_handler.config[:default_error_template]

    log_error(["Could not find an error template in the usual places " +
              "for exception #{exception.class}, status code " +
              "#{status_code}.",
              "Trying to default to app-specific default: '#{file_path}'"])
  end

  # as a last resort, just render the gem's 500 error
  if file_path.blank? || !File.exists?(file_path)
    file_path = Wrangler::ExceptionHandler.config[:absolute_last_resort_default_error_template]

    log_error("Still no template found. Using gem default of " +
              file_path)
  end

  log_error("Will render error template: '#{file_path}'")

  options = { :file => file_path, :status => status_code }

  unless Wrangler::ExceptionHandler.config[:render_error_options].blank?
    options.merge! Wrangler::ExceptionHandler.config[:render_error_options]
  end

  render options
end

#rescue_with_handler(exception) ⇒ Object

called by rails if the exception has already been handled (e.g. by calling the rescue_from method in a controller and rendering a response)




78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/wrangler.rb', line 78

def rescue_with_handler(exception)
  to_return = super
  if to_return &&
       (
         (local_request? && Wrangler::ExceptionHandler.config[:handle_local_errors]) ||
         (!local_request? && Wrangler::ExceptionHandler.config[:handle_public_errors])
       )

    handle_exception(exception, :request => request,
                                :render_errors => false)
  end
  to_return
end