Drupal 8 or 9 で致命的なエラーが発生した時に表示される 500エラーページをカスタマイズする方法を紹介します。
500エラーページとはこういうメッセージが表示されるやつです:
The website encountered an unexpected error. Please try again later.
選択肢
a) Drupal だけで対応する場合
- Drupal 9.0.7 時点では、コアのエラー処理をカスタマイズする方法は用意されておらず、スマートな実現方法はない
- エラーの発生場所、内容によってはカスタマイズが不可能な場合もある (
settings.php
でのエラーなど)
選択肢
- 実行時にエラーハンドラを独自のものに置き換える
- この方法で実装された error_page モジュールが存在
- コアのコードをコピペ & 修正してエラーハンドラをまるごと置き換える必要があり、コアのアップデートに追従できないリスクがある
- コアのエラーハンドラを修正する
- 自前で修正する
- 奥の手
- Drupal.org の issue (Ability to Customize Core Error Message [#3108689] | Drupal.org) のパッチを利用する
- ★ 次点でこれ
- 自前で修正する
b) CDN などの上位層で対応する場合
- CDNで対応
- ★ 使えればこれがベスト
- CloudFront の場合: 特定の HTTP ステータスコードのカスタムエラーページを作成する - Amazon CloudFront
- 静的なHTMLページを用意する
- Apache でがんばる
-
mod_ext_filter
を使えばできないことはないが、色々デメリットがあるため非現実的 - フィルタプログラムを作る手間とかパフォーマンスへの影響とか
-
以下では、#3108689 のパッチを利用してDrupalだけで対応する方法について考えます。
a.2.2) #3108689 のパッチを利用する方法
CDNでの対応ができない場合は、次点でこれが一番マシだと思われます。
Drupal.orgで、500エラーページのメッセージをカスタマイズする機能を追加するissueが進行中で、
Ability to Customize Core Error Message [#3108689] | Drupal.org
パッチの内容には大きな問題はなさそうでですが、まだマージされていないため使うには自前でパッチを当てる必要があります。
また、issueに添付されている 3108689-51.patch
のパッチは、drupal/core パッケージには存在しないファイル (sites/default/default.settings.php
) のdiffが含まれるため、そのdiffを取り除いてから適用する必要があります。
(cweagans/composer-patches
プラグインを使ってパッチを当てることを想定)
使い方
-
#3108689 のパッチから不要な diff を削除したファイルをリポジトリに追加する
-
sites/default/default.settings.php
のdiffを消す - 修正したパッチを
[repo-root]/patches/drupal/core/3108689-51--mod.patch
などに置く
-
-
composer.json
のextra.patches.drupal/core
にパッチのパスを追加 -
composer install
実行 -
settings.php
で$settings['custom_error_message']
にエラーページの内容 (HTML) を設定する
気をつけること
- 完全に静的な HTML 文字列を
$settings
に設定する- CSSファイルなどへのURLも絶対URLで直接記述する
- 内容を動的に変えることはできない
-
settings.php
に直接HTMLを書く必要がある- HTMLファイルに分離すると必要ないときもファイル読み込みが発生してしまうため
使用例
"extra": {
"patches": {
"drupal/core": {
"3108689 Ability to Customize Core Error Message": "patches/drupal/core/3108689-51--mod.patch"
}
},
$settings['custom_error_message'] = <<<'HTML'
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>エラーです</title>
<style>
body {
width: 400px;
margin: 0 auto;
}
h1 {
background-color: red;
color: white;
}
</style>
</head>
<body>
<h1>エラーです</h1>
<p>何かやばいエラーが発生しました。</p>
<p>しばらく待ってから再読み込みしてみてください。</p>
<p><a href="/">トップページを開く</a></p>
</body>
</html>
HTML;