「.png」「.jpg」などの拡張子が付くパスだと、「404」のエラーハンドリングが機能せず「Missing template」になる問題(Rails)

【結論】

・存在しないパスにアクセスした場合、エラーハンドリング で指定した「404」のビューファイルに飛ぶ様に設定しているにも関わらず、「.png」や「.jpg」といった拡張子で終わるパスにアクセスした場合、「Missing template」になることがある。

・「.png」などの拡張子で終わるパスにアクセスすると、formatsが[:png]などになるが、デフォルトのフォーマットはhtmlなので、指定したファイルが「.png」で無いと「missing template」が返ってしまい、エラーハンドリング が出来ない事が原因。

・この場合、html以外のformatsに対する処理も記述すれば改善する

【目次】

【本題】

事象:「.png」「.jpg」などの拡張子が付くパスだと、エラーハンドリングが機能しない

存在しないパスなどにアクセスしてrouting error(404)になった場合、rescue_fromでエラーをキャッチして、独自の404ページに飛ばす様に設定しているにも関わらず、「Missing template」が発生する事があります。

今回はその原因と対策について、まとめます。

なお、エラーは、「.png」「.jpg」などの拡張子が付く存在しないパスにアクセスした際に発生しています。

※エラーハンドリング については、過去記事参照

https://ryoutaku-jo.hatenablog.com/entry/2019/05/08/%E3%82%A8%E3%83%A9%E3%83%BC%E3%83%8F%E3%83%B3%E3%83%89%E3%83%AA%E3%83%B3%E3%82%B0%EF%BC%88%E4%BE%8B%E5%A4%96%E5%87%A6%E7%90%86%EF%BC%89%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6ryoutaku-jo.hatenablog.com

https://ryoutaku-jo.hatenablog.com/entry/2019/05/08/%E3%82%A8%E3%83%A9%E3%83%BC%E3%83%9A%E3%83%BC%E3%82%B8%E3%81%AE%E5%AE%9F%E8%A3%85%E6%96%B9%E6%B3%95ryoutaku-jo.hatenablog.com

ryoutaku-jo.hatenablog.com

原因:エラーハンドラ内のメソッドがhtml形式以外のリクエストを処理できない

以下が実際のエラー画面ですが、:formats=>[:png]となっている事が分かります。

拡張子をパスに指定すると、その拡張子(フォーマット)に対応したテンプレートを探し出します。

しかし、エラーページを読み込み処理は、以下の様に記述されています。

render 'errors/error_404', status: :not_found

また、errorsフォルダ配下にはpng形式などのファイルは存在しません。

その為、フォーマットに対応したテンプレートが存在しないので、エラーハンドリング 出来ず、「Missing template」となっていました。

対策:html以外のフォーマットはエラーハンドラにリダイレクトさせる

「.png」などでも404エラーを返したい場合は、以下の様に、html以外のフォーマットは404ハンドラにリダイレクトさせる処理を追記する事で改善されます。

respond_to do |format|
  format.html { render 'errors/error_404', status: :not_found, layout: 'lp' }
  format.all { redirect_to controller: 'errors', action: 'not_found' }
end

参考情報

actionview - Internal server error 500 on missing image file (Rails 3.2.12) - Stack Overflow

Ruby on Rails4.2で.pngや.jpgや.jsonへの404エラー対応 - Qiita

Rails: Missing template エラーの扱い - Qiita