Read more

How to not die with ActionView::MissingTemplate when clients request weird formats

Henning Koch
April 26, 2013Software engineer at makandra GmbH

When HTTP clients make an request they can define which response formats they can process. They do it by adding a header to the HTTP request like this:

Accept: application/json
Illustration UI/UX Design

UI/UX Design by makandra brand

We make sure that your target audience has the best possible experience with your digital product. You get:

  • Design tailored to your audience
  • Proven processes customized to your needs
  • An expert team of experienced designers
Read more Show archive.org snapshot

This means the client will only understand JSON responses.

When a Rails action is done, it will try to render a template for a format that the client understand. This means when all you are HTML templates, a request that only accepts application/json will raise an error:

An ActionView::MissingTemplate occurred in pages#foo:
  Missing template pages/foo, application/foo with {:locale=>[:de], :formats=>[:json], :handlers=>[:erb, :builder, :haml]}

This is because Rails tried to find a template like foo.js.erb but all it found was foo.html.haml (which the client doesn't understand).

Why does someone request my page with weird formats?

Stupidity. Anyway you cannot prevent people from making such requests.

What can I do to prevent this error?

Option: Don't care

You can choose not to care. Since e.g. making JSON requests for HTML services is not supported use of your page, you don't have to support them with a proper response.

Option: Declare supported formats in your routes

You can define your routes for certain formats only:

# routes.rb
contraints(:format => /html/) do
  match 'foo' => 'pages#foo'
end

Now JSON requests will get a 404 Not found error, which is slightly less correct than a 406, but will serve your purpose.

Option: Check the format in your actions

You can write something like this in your controller action:

def foo
  respond_with do |format|
    format.html { render 'foo' }
  end
  # or shorter: respond_to :html
end

Now JSON requests will get a 406 Not acceptable error, which is correct.

Posted by Henning Koch to makandra dev (2013-04-26 14:27)