Ruby on Railsでカスタム404、500エラーページを作成する方法 - 完全ガイド

## Ruby on Railsにおける標準のエラーページとは
問題が発生した場合に表示されるページで、Ruby on Railsでは、様々な種類のエラーに対応するエラーページが標準で提供されています。

404エラーは、クライアントエラーを示し、通常はユーザーの要求が正しくないことを示します。一方、500エラーはサーバーエラーを示し、アプリケーションが要求を処理するのに問題があることを示します。

Railsのデフォルトのエラーページは、以下のようなものです。

#### 404エラー
![スクリーンショット 2023-08-05 10.52.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35605/3c75728d-6965-5a49-6a70-e8ef43ebbbb5.png)

#### 50xエラー
![スクリーンショット 2023-08-05 10.53.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35605/7403cefa-6794-ac9e-0de3-affa70c8beb2.png)

## カスタムエラーページが必要な理由
カスタムエラーページを使用すると、ユーザー体験を向上させることができます。例えば、ブランドのスタイルに合わせたデザインや、ユーザーが次に何をすべきかを示す役立つ情報を提供することが可能です。

## Ruby on Railsでのカスタム404エラーページの作成方法

カスタム404エラーページを作成するための手順は非常にシンプルです。以下に、実装に必要なコードを示します。

### レイアウト

まず、エラーページ用のレイアウトを設定します。内容としては`= yield`ぐらいで十分です。

```slim:app/views/layouts/error.html.slim
doctype html

html lang='en'
  head
    meta charset='utf-8'
    meta name="viewport" content="width=device-width,initial-scale=1"

    title Error

    = csrf_meta_tags
    = csp_meta_tag
    = favicon_link_tag 'favicon.ico'

    = vite_client_tag
    = vite_javascript_tag 'application'

  body
    = yield
```

### コントローラー

次に、新たなエラーページを管理するアクションとそれに対応するビューを作成します。以下のコードスニペットは、カスタム404エラーページをレンダリングするためのアクションとビューを示しています：

```ruby:app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  rescue_from ActiveRecord::RecordNotFound, with: :render404

  def render404(error = nil)
    Rails.logger.error("❌#{error.message}") if error
    render template: 'errors/render404', layout: 'static_page', status: :not_found
  end
end

```

### ビュー

そして、404エラーページのビューを作成します。そこにホームページに戻るリンクを入れるとユーザーには便利だと思います。

```slim:app/views/errors/error404.html.slim
div class="mt-12 flex flex-col space-y-8 items-center justify-center"
  div = image_tag 'system_icons/404.png'
  h1 class="text-red-700 text-xl md:text-3xl" Sorry! This page is not available.
  = link_to '<<< Back', root_path, class: 'text-xl text-blue-500'
```

### ルーティング

最後に、新しいエラーページが適切に表示されるように、ルーティングを設定します。以下のコードは、カスタム404エラーページへのルーティングを示しています：

```ruby:config/routes.rb
Rails.application.routes.draw do
  # 省略

  get '*path', to: 'application#render404'
end
```

試しには、例えば`localhost:3000/hoge/hoge`などという存在しないページ、または存在しないレコードのページにアクセスするとカスタムの404ページが表示されるはずです。

![スクリーンショット 2023-08-05 10.59.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35605/58f3cdb5-cfea-bb6d-ddd8-41d8f4d4a308.png)

## Ruby on Railsでのカスタム500エラーページの作成方法

### コントローラー

サーバーエラーをハンドリングするアクションを追加します：

```ruby:app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  rescue_from StandardError, with: :render500

  def render500(error = nil)
    Rails.logger.error("❌#{error.message}") if error
    render template: 'errors/render500', layout: 'static_page', status: :internal_server_error
  end
end
```

### ビュー

```slim:app/views/errors/error500.html.slim
div class="mt-12 flex flex-col space-y-8 items-center justify-center"
  div = image_tag 'system_icons/500.png'
  h1 class="text-red-700 text-xl md:text-3xl" Oops! Something went wrong
  p class="text-lg" Please be patient or try again later.
  = link_to '<<< Back', root_path, class: 'text-xl text-blue-500'
```

サーバーエラーが発生するとカスタムの500ページが表示されるはずです。

![スクリーンショット 2023-08-05 11.32.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35605/681c398d-7031-0517-9fd9-b61adbc4a08f.png)

### rescue_fromに関する注意点

`rescue_from`を複数記述した場合は下から上までの順番に動作します。従って、`ApplicationController`に定義する`rescue_from`はこのような順番で定義してください。

```ruby:app/controllers/application_controller.rb
  rescue_from StandardError, with: :render500                # 二番目に動作
  rescue_from ActiveRecord::RecordNotFound, with: :render404 # 一番目に動作
```