Strange MissingTemplate exception with :formats=>[:jpeg, "image/pjpeg", :png, :gif] - ruby-on-rails

In production, we regularly get the following exception:
An ActionView::MissingTemplate occurred in constructions#show:
Missing template constructions/show, application/show with {:locale=3D>[:=
ru], :formats=3D>[:jpeg, "image/pjpeg", :png, :gif], :handlers=3D>[:erb, :b=
uilder, :coffee, :jbuilder, :haml]}
What puzzles me here is the formats hash, which requests for some image (:jpeg, "image/pjpeg", :png, :gif). We have no custom MIME types registered in our app, and as far as I know there's no corresponding Rails default MIME-type.
So the question is: what kind of request generates this formats hash?

I got same error as well. I notices this is from a search engine of "YandexImage" trying to get custom format. On my controller and action is just empty, because it is a static *.html.erb page. Here is more information.
* DOCUMENT_ROOT : /srv/www/apps/mysite/current/public
* HTTP_ACCEPT : image/jpeg, image/pjpeg, image/png, image/gif
* HTTP_CONNECTION : Keep-Alive
* HTTP_FROM : support#search.yandex.ru
* HTTP_HOST : mysite.com
* HTTP_USER_AGENT : Mozilla/5.0 (compatible; YandexImages/3.0; +http://yandex.com/bots)
* ORIGINAL_FULLPATH : /
Two ways to fix this:
Edit public/robots.txt to block YandexImage. see more information at http://yandex.com/bots
User-agent: YandexImage
Disallow: /
Or put following code to your action, it will handle only html otherwise raise the not found page
respond_to do |format|
format.html
format.any { raise ActionController::RoutingError.new('Not Found') }
end

Related

Problem with sitemap.xml in Ruby on Rails app

I have Ruby on Rails app and I created sitemap.xml file (in public directory) with sitemap_generator gem but it can't be readable in production.
sitemap.rb
# Set the host name for URL creation
SitemapGenerator::Sitemap.default_host = "https://example.com"
SitemapGenerator::Sitemap.namer = SitemapGenerator::SimpleNamer.new(:sitemap, :extension => '.xml')
SitemapGenerator::Sitemap.create do
Category.find_each do |cat|
add category_path(cat), priority: 0.8, changefreq: 'daily', lastmod: cat.updated_at
end
Job.where(status: true).find_each do |job|
add job_path(job), priority: 0.6, lastmod: job.updated_at
end
end
errors_controller.rb
class ErrorsController < ApplicationController
def not_found
render status: 404
end
def unprocessable_entity
render status: 422
end
def internal_server_error
render status: 500
end
end
I have all views for each kind of errors but Heroku logs show me:
I, [2019-10-16T11:57:53 #4] INFO -- : Processing by ErrorsController#not_found as XML
I, [2019-10-16T11:57:53 #4] INFO -- : Completed 500 Internal Server Error in 2ms (ActiveRecord: 0.0ms)
2019-10-16T11:57:53 app[web.1]: Error during failsafe response: Missing template errors/not_found, application/not_found with {:locale=>[:en], :formats=>[:xml], :variants=>[], :handlers=>[:raw, :erb, :html, :builder, :ruby, :coffee, :jbuilder, :haml]}. Searched in:
2019-10-16T11:57:53 app[web.1]: * "/app/app/views"
The command heroku run rails sitemap:refresh:no_ping is creating all links that I want but when I try to see the link https://mywebsite.com/sitemap.xml - I get 500 error and I can't see the content - I don't know why. I think it can be some problems with error controller because https://mywebsite.com/sitemap (without .xml) displays 404 page. With .xml it is 500 error.
On localhost everything works fine but in production mode on Heroku I have problems.
As I know, sitemap_generator creates sitemap.xml.gz file. Try open your-site.com/sitemap.xml.gz. Works on my project.

Rails 4 - MissingTemplate/Missing Partial Error, Only in Production

We just secured our application with an SSL certificate. Moving to HTTPS is proved more complex than we thought and we're currently sorting through a few of the resulting bugs.
We have an AJAX call in CoffeeScript, where rails responds by rendering the html of a partial. This is working perfectly in development.
CoffeeScript:
coffee_method: (pos, uid) =>
$.ajax '/contoller/test/',
type: 'POST'
data:
pos: pos
uid: uid
success: (data) ->
$('#result-div').html(data) #Populates side menu with _next_destination_menu content
error: ->
alert 'How embarassing! Something went wrong - please try your search again. '
Controller:
def test
... #do some stuff
puts "format requested: #{request.format}"
puts "format url_encodeded: #{request.format.url_encoded_form?}"
render partial: 'trips/_test' #app/views/trips/_test.html.erb
end
However, in production, we get the following error:
ActionView::MissingTemplate (Missing partial trips/_test with {:locale=>[:en], :formats=>[:url_encoded_form], :variants=>[], :handlers=>[:erb, :builder, :raw, :ruby, :coffee, :jbuilder]}.
After some digging, I figured out the request in production was a different format. Using those puts lines in the controller to debug, here are the results:
Production:
format requested: application/x-www-form-urlencoded
format url_encodeded: true
Development:
format requested: */*
format url_encodeded: false
What is the best way to handle this issue. Do I:
Change the content type of every AJAX call in the CoffeeScript?
Add a respond_to...format.url_encoded_form {render partial: trips/test} to the controller?
The latter seems like I would be duplicating code, because I want to render the same partial, regardless of the format the request comes in. I tried format.all {...} but encountered the same issue. Any best practices are appreciated!
Update:
Specifying the response type directly gives me the same missing template error:
respond_to do |format|
format.html {render partial: 'trips/test'}
format.json {render partial: 'trips/test' }
format.url_encoded_form {render partial: 'trips/test'}
end
Update 2:
The Request headers for both localhost and production are the same, the content type is application/x-www-form-urlencoded, even though format.url_encoded_form? returns false.
Accept:*/*
Accept-Encoding:gzip, deflate, br
Accept-Language:en-US,en;q=0.8,zh-CN;q=0.6,zh;q=0.4
Connection:keep-alive
Content-Length:37
Content-Type:application/x-www-form-urlencoded; charset=UTF-8
You could try passing in the format, locale, and handlers exactly as requested:
render(
   partial: 'trips/test',
     formats: [:html, :js, :json, :url_encoded_form],
     locale: [:en],
     handlers: [:erb, :builder, :raw, :ruby, :coffee, :jbuilder])

rails4 // ActionController::UnknownFormat

Some bots or other external requests cause an ActionController::UnknownFormat error when redirecting
Is there a catch-all method to add somewhere in application_controller to handle those errors ?
A config spec to add a default method in request (if none specified) ?
Below an example of trace :
An ActionController::UnknownFormat occurred in main#index:
ActionController::UnknownFormat
app/controllers/main_controller.rb:17:in `index'
-------------------------------
Request:
-------------------------------
* URL : http://ownedurl.com/
* HTTP Method: GET
* IP address : 82.xxx.xxx.xxx
* Parameters : {"controller"=>"main", "action"=>"index"}
* Timestamp : 2015-06-07 20:54:32 +0200
* Server : servername
* Rails root : /var/www/ownedurl.com/releases/208
* Process: 29726
A get request would obviously work; yet it makes it occurs.
Experiences on this one appreciated
thx a lot
This will handle a request without format :
rescue_from ActionController::UnknownFormat, with: :raise_not_found
def raise_not_found
render(text: 'Not Found', status: 404)
end
You can supply the :format to your routes itself to tell it what are the formats are valid and which are not.
Read some discussions on this and this answer.

Get "ActionView::MissingTemplate" error, when I post json to rails controller from angular

I use angularjs in my new ruby on rails project. I create my view with angularjs and back end server with ruby on rails.
Now, I have a form in angular part, when user complete the form and click on send, I post a json like below to server:
$scope.jsonList = {
"form1": {name:"John",lastName:"Smart"},
"form2": {job:"student",age:"18"}
};
I post this json to a test action in rails controller. I put javascript (angularjs) and server side code below:
angularController:
//Services
.factory('Test', function($resource){
return $resource('/api/test.json', {}, {
create: { method: 'post'}
});
})
//Angular Controller
$scope.testResponse = Test.create(angular.toJson($scope.jsonList));
and routes.rb:
namespace :api, defaults: {format: :json} do
scope module: :v1, constraints: ApiConstraints.new(version: 1, default: :true) do
match '/test',to:'dropdowns#test', via: 'post'
end
end
and dropdownsController:
class Api::V1::DropdownsController < Api::V1::BaseController
def test
end
end
I do all this, but when I post json to rails server, I recieve json, but I get below error:
Started POST "/api/test.json" for 127.0.0.1 at 2014-11-22 17:11:10 +0330
Processing by Api::V1::DropdownsController#test as JSON
Parameters: {"form1"=>{"name"=>"John", "lastName"=>"Smart"}, "form2"=>{"job"=>"student", "age"=>"18"}, "dropdown"=>{"form1"=>{"name"=>"John", "lastName"=>"Smart"}, "form2"=>{"job"=>"student", "age"=>"18"}}}
Completed 500 Internal Server Error in 1ms
ActionView::MissingTemplate (Missing template api/v1/dropdowns/test, api/v1/base/test with {:locale=>[:en], :formats=>[:json], :variants=>[], :handlers=>[:erb, :builder, :raw, :ruby, :coffee, :jbuilder]}. Searched in:
* "/Users/mgh/Documents/Maliat/sama/app/views"
):
actionview (4.1.6) lib/action_view/path_set.rb:46:in `find'
actionview (4.1.6) lib/action_view/lookup_context.rb:124:in `find'
actionview (4.1.6) lib/action_view/renderer/abstract_renderer.rb:18:in `find_template'
actionview (4.1.6) lib/action_view/renderer/template_renderer.rb:41:in `determine_template'
I can do any thing with json when I recieve in rails controller (like parse and puts on console and save in database with other controller), but at the end of controller, I get above error and I cannot post any response to angular part. Where is the problem?
How can I fix this error?
You are not explicitly rendering anything in the test method so rails is looking for a template to send back as a response. However, you don't have a json template in your api/v1/dropdowns/ folder (I think it will look for a file called test.json in your case).
You can solve this by either sending back a response explicitly, (check out this guide for more about rendering a response.
def test
render plain: "This is the response from 'test' method in DropDownsController"
end
or you want to return json of a model
def test
render json: #product
end
OR
You can put a template in your api/v1/dropdowns/ folder and rails will serve that instead. But the overall point is you need to send back a response.
For example:
api/v1/dropdowns/test.json.erb
{
"name" : "my name is greg or something"
}

Intermittent Ruby on Rails log (ActionView::MissingTemplate)

I keep seeing errors in my logs similar to the below.
Can anyone suggest why I could be getting such an error intermittently? Is it a caching issue?
Every time I attempt to load the about-us page it loads perfectly but every few days there's an error like this in my logs but it's not confined to a single page. Sometimes it's the homepage, some times it's other pages.
Started GET "/about-us" for xxx.xxx.xxx.xxx at 2014-08-16 07:54:06 +0100
Processing by PagesController#about as */*;q=0.6
Geokit is using the domain: mydomain.com
[1m[35mPage Load (0.2ms)[0m SELECT `pages`.* FROM `pages` WHERE `pages`.`name` = 'About Us' LIMIT 1
Completed 500 Internal Server Error in 2ms
ActionView::MissingTemplate (Missing template pages/about, application/about with {:handlers=>[:erb, :builder, :arb], :formats=>["*/*;q=0.6"], :locale=>[:en, :en]}. Searched in:
* "/var/www/myapp/releases/201408150651/app/views"
* "/var/lib/ruby-rvm/gems/ruby-1.9.2-p320/gems/activeadmin-0.3.2/app/views"
* "/var/lib/ruby-rvm/gems/ruby-1.9.2-p320/gems/kaminari-0.12.4/app/views"
* "/var/lib/ruby-rvm/gems/ruby-1.9.2-p320/gems/devise-1.4.7/app/views"
):
This question is similar to: Random rails ActionView::MissingTemplate errors so this is happening to other people but there's no defined answer there either.
You can't prevent this error as there are load reasons(like you mentioned missing cache, unknown request format and etc)
You can try to restrict the number of predefined formats like:
get '/about-us' => 'controller#about', :format => /(?:|html|json)/
Also you can suppress this exception. Create a new file(for example exception_handler.rb) in the directory config/initializers and Add this line into created file:
ActionDispatch::ExceptionWrapper.rescue_responses.merge! 'ActionView::MissingTemplate' => :not_found
Hope it helps.
#ProblemSolvers is a possible solution. However, I added the following method in my application_controller.rb file so that such errors will render a 404 page rather failing with a error message on screen
rescue_from ActionView::MissingTemplate, :with => :rescue_not_found
protected
def rescue_not_found
Rails.logger.warn "Redirect to 404, Error: ActionView::MissingTemplate"
redirect_to '/404' #or your 404 page
end
you can wrap this code in a if statement, something like this if Rails.env.production? given that the env is setup so your dev environment wont be affected

Resources