How do I prevent unwanted routing errors in production - ruby-on-rails

ActionController::RoutingError (No route matches [GET] "/google83362a7a0f381ff0.html"):
I see the above logs in production, how should I prevent it.
If user mistypes a URL, how should I re-direct to a common error page

You can redirect the user to the desire page you want if no route matchs
Write down the following code at the bottom of your routes.rb file
In /config/routes.rb
#If no route matches
match ":url" => "application#redirect_user", :constraints => { :url => /.*/ }
Then redirect the user to the error page in the application_controller.rb file
*In /app/controllers/application_controller.rb*
def redirect_user
redirect_to '/404'
end

You don't need to trigger a controller to do that.
Just add this as the last rule in routes.rb:
match '*path', via: :all, to: redirect('/404')

Rails does this automatically when application running in production mode.When uploading application to live server, Rails takes care of handling those exceptions and rendering the correct error pages with the correct header status.You can directly find the files inside public folder.
Whenever you set up your Rails application on a live server, you give the site root as the /public folder in your application. Then, whenever a request is made to that server address, Web server first looks in that public folder and tries to serve a static asset (this is a configurable option in config/environment.rb). If it can't find the requested page, then the request is forwarded through the Ruby stack.
When in production mode, if Rails encounters an error that isn't handled, it throws the error to the stack, which then tells Web server to render an appropriate error.
Here are some common errors that you'll see in development mode and what they render in production mode:
ActiveRecord::RecordNotFound => 404 (page not found)
nil.method => 500 (server error) unless you turn off whiny nils
ActionController::RoutingError => 404 (page not found)

Related

Rails Routing to Unknown Pages is Messing Up With ActiveStorage Image Path

I searched for every code that I can find here in stackoverflow on how you actually can redirect the pages that doesn't exist or unknown to a 404 page.
For instance you visited this page http://localhost:3000/thispageisnull since the page doesn't exist it will automatically redirect you to the default 404 custom page I created.
So far here's what I did. On my errors_controller.rb file I place this code:
def show_404
render "404", status: 404
end
And then on my routes.rb file, I place this code:
match '*path', via: :all, to: 'errors#show_404'
This basically works for me as it redirects all of the unknown pages to 404 page. However, it seems it's messing up with the ActiveStorage images path.
Whenever I am placing these codes and redirecting every page that doesn't exist to 404, it's always making my ActiveStorage images broken. As in like this image: https://imgur.com/OCrWQLQ
And if I remove these piece of codes about the 404 redirection, it always turn back to normal images.
What is the best way to do a redirection to 404 page w/o affecting the ActiveStorage images?
You can try doing something like this which might help, in your routes.rb change the line like this:
match '*path', via: :all, to: 'errors#show_404', constraints: lambda { |req|
req.path.exclude? 'rails/active_storage'
}
So it will exclude that path and let the application show the images. Please change the path as per your requirement (I think it should be rails/active_storage only)

New rails installation with error when entering url

SOLVED In the /etc/apache2/vhosts.d/default.conf we inserted the following
RewriteEngine On
RewriteRule "^/?$" "http://ourpage.com/projects"
--------------------------------------------------------------------------------------------------------------
We installed rails on a new server. When we try access the url we get redirected to ourstuff/public which is not desired. In ourstuff there is app, config, public etc.
EDIT:
Could it be that the mod passenger does not work properly?
The following from public is displayed in the browser (see scrshot). My collegaue said its from the the documentary root from the apache config file.
public
When we try the usual url xyz.com/ourstuff like from our other systems we get this error
Routing Error
No route matches [GET] "/ourstuff"
Try running rake routes for more information on available routes.
Does anyone have an idea why this is?
Thank you in adcvance.
Have you set up your routes?
In your config/routes.rb file add:
get '/ourstuff', to: 'controller#action', as: 'ourstuff'
This means when your server receives a get request to yourapp.com/ourstuff, it will send the request to the controller and action you specify.
It's then up to you to put in the required logic in that action, and present the relevant template. See:
http://guides.rubyonrails.org/routing.html
EDIT: You need to add this line inbetween:
myqpp::Application.routes.draw do
and the final
end
on its own line. i.e.
myqpp::Application.routes.draw do
root :to => 'projects#index'
get '/ourstuff', to: 'controller#action', as: 'ourstuff'
end
Once more, you will need to set up a controller, an action for that controller with the necessary logic, and a template to render at the end.

How do I prevent my routes.rb from intercepting requests coming to /blog?

My /blog directory is just a bunch of static HTML files. That's good.
When I go to localhost/blog it works fine - it renders the index.html for my middleman generated blog. Great.
But when I click on any of the posts, it gives me a routing error:
No route matches [GET] "/blog/2015/03/11/hello_world"
I am pretty sure the reason this is happening is because of one of these rules in my routes.rb:
get '/:friendly_id', to: 'posts#show'
get '/rbt/:name', to: redirect {|path_params, _| "/#{path_params[:name].gsub(/^\d+\-/, '')}" }
get ':name', to: 'posts#show'
I need all of these routes, but I don't want an HTML request to hit my Rack middleware unnecessarily....or worse yet, do a DB query which this error seems to suggest is happening.
How do I confine all requests to /blog/ to just resolve to my public/blog/ directory?
Edit 1
I realize the above description may not be clear. My Rails App isn't a blog, and so the posts you see referenced above, are not posts to the blog. They are posts of another kind, separately managed by the Rails app with a DB and all. I have since added a real /blog which will just be a collection of HTML articles generated by MiddleMan that will sit in my Rails /public/blog folder. The idea being that the HTML files in my /blog directory, should not hit my Rack middleware at all.
You can force rack to serve certain folder as static and routes-ignoring by adding config.middleware.use Rack::Static, urls: ['/blog'], root: 'public' to config/application.rb but imho it's better to setup a web server to intercept and serve /blog earlier than your app does.
And also in your case /blog/2015/03/11/hello_world seems to be a directory name, if you add index.html to the link it should work as you expect, without changing any configuration.
When your app is run by webserver, its webroot will be the public directory. So, if you have your blog directory inside public directory this should work. localhost/blog
Try running with nginx with following config :
root /root/path/to/your_app/public;
Couldn't you create a static_url controller and configure your routes so that
get '/blog', to: 'static_url#show'
Then in your controller have
def show
render file: request.fullpath
end
Sorry I can't test right now but I'm sure you get the idea. Also, I guess you would need to detect non-existent pages.

How do I ignore a route in rails?

I have a route i.e. mysite.com:3000/new_route that I'd like to ignore, is this possible to do through rails and not server side?
I've read that this can be done through apache, however, my app is running on Heroku and that type of control isn't accessible to me. Therefore, I'm looking for another way to do this through Rails.
Thanks
update
I am using faye to have live notifications in my app, on localhost faye runs on port 9292 - localhost:9292/faye, all good in development mode, but in production it should point to mydomain.com/faye, there are no port numbers in production environment, and loading faye.js returns error not found
If you're talking about a resources route you don't want to be created:
resources :something, except: :new
However, I'm not exactly sure if this is what you meant by ignore.
You can define a route at the top of your routes.rb file that will redirect to some other page.
get '/new_route', redirect: '/'
By the time you ask Rails to process the route, it is already too late. If you ask rails to process a route, it will, either by returning a 404 of 500 error, or a page.
If you want the route to be processed by another application, it will need to be intercepted by your webserver (nginx or apache, or whichever one you're using). In their configuration, you just redirect that route to the other application, and every other route to the Rails app.
EDIT
Another option you have, is to forward your requests to a different server.
You add a route like
get 'faye/*query' => 'faye#get'
post 'faye/*params' => 'faye#post'
And then a controller
require 'faraday'
class FayeController < ApplicationController
APP = 'http://mydomain.com:9292'
def get
request_page :get
end
def post
request_page :post
end
private
def request_page(method)
conn = Faraday.new(:url => APP)
query = params.delete(:query)
response = conn.send method, query, params
render text: response.body.gsub(APP, 'mydomain.com/faye')
end
end
which will use Faraday to load the information from your other application.

Rescuing a RoutingError in Rails

So, I followed José Valim's blogpost, adding
config.exceptions_app = self.routes
to my application.rb for routing HTTP errors to my own controller.
Everything works just as it's supposed to, my custom error pages work and such, but it throws an ActionController::RoutingErrorthough, which gets logged as FATAL. Is there anyway to get around that FATALmessage? I've been trying to rescue from the error both in the application controller and in my error controller, but to no avail.
2012-06-27 12:19:33.908 [FATAL] [127.0.0.1]
ActionController::RoutingError (No route matches [GET] "/3489423u4023ho")
Did you add a route like match "/404", :to => "errors#not_found"?
Are you using the production mode, or the development mode?
You won’t be able to see your custom exceptions in development unless you set config.consider_all_requests_local to false in your config/environments/development.rb. The reason is, if the request is considered local, Rails will always favor to show the debug exceptions page;

Resources