Rails 3.2 error routing error. Error ID conflicts with another object ID

We just upgraded our application to Rails 3.2.2 and now we have a routing issue for error handling.

In the José Valim blog post , we added the following:
config.exceptions_app = self.routes

in config / application.rb
match "/404", :to => "errors#not_found"

in config / routes.rb
(and the corresponding controller / views).

The problem is what we need ourdomain.com/id

to display the index page for the product category id

.

So now it ourdomain.com/404

shows our 404 page when it should be showing our category listing page for a category id

from 404.

How can we get around this?
Is there a way for the app to add each bug with error_

before it was evaluated with routes

?
Or maybe somehow set config.exceptions_app

to reference the namespace in the file routes

?
Or can I create a second set of routes and install config.exceptions_app = self.second_set_of_routes

?

Thank!

+3


source to share


3 answers


There is one solution I have found so far:

# application_controller.rb

def rescue_404
  rescue_action_in_public CustomNotFoundError.new
end

def rescue_action_in_public(exception)
  case exception
    when CustomNotFoundError, ::ActionController::UnknownAction then
      #render_with_layout "shared/error404", 404, "standard"
      render template: "shared/error404", layout: "standard", status: "404"
    else
      @message = exception
      render template: "shared/error", layout: "standard", status: "500"
  end
end

def local_request?
  return false
end

      

rescue_action_in_public

is the method that Rails calls to handle most errors.
local_request?

the method tells Rails to stop sucking if it's a local request

# config/routes.rb
match '*path', controller: 'application', action: 'rescue_404' \
  unless ::ActionController::Base.consider_all_requests_local

      

It just says that it cannot find any other route to handle the request (i.e. *path

), it must invoke an action rescue_404

on the application controller (first method above).



EDIT

This version worked well for me! Try adding toapplication.rb

# 404 catch all route
config.after_initialize do |app|
  app.routes.append{ match '*a', to: 'application#render_not_found' } \
    unless config.consider_all_requests_local
end

      

See: https://github.com/rails/rails/issues/671#issuecomment-1780159

+1


source


We had the same problem - error codes colliding with resource IDs at the root level (for example collisions between ourdomain.com/:resource_id

and ourdomain.com/404

).

We've modified José Valim's solution to add a route restriction that only applies when handling an exception:



# Are we handling an exception?
class ExceptionAppConstraint
  def self.matches?(request)
    request.env["action_dispatch.exception"].present?
  end
end

MyApp::Application.routes.draw do
  # These routes are only considered when there is an exception
  constraints(ExceptionAppConstraint) do
    match "/404", :to => "errors#not_found"
    match "/500", :to => "errors#internal_server_error"

    # Any other status code
    match '*a', :to => "errors#unknown"
  end
  ...
  # other routes, including 'match "/:resource_id"'
end

      

(We just stumbled upon this solution last night, so it didn't have a lot of recording time. We're using Rails 3.2.8)

+4


source


This route seems to be hardcoded with show_exceptions method ( see source )

Sorry, but I don't think of how to do this, other than changing line 45 on the source above:

env["PATH_INFO"] = "/error_#{status}"

      

(which, of course, no solution at all).

It doesn't hurt to ask: if you think it would be nice if your own error controller was so easy to implement and desperate to have, than it wouldn't be even more "RESTful" if your route were your home. com / product /: id

+1


source







All Articles