Language - Japanese / English
Introduction
前回、Drupal11.4.0にアップデートした際、Symfonyのruntimeに関わるエラーを修復しました。動作確認として、各ページの表示を確認しながらエラーチェックを行うと、Civic Themeの検索用モジュールであるSearch APIの表示でエラーが発生しています。
今回は、Search APIの表示で発生したエラーの修復についてまとめてみました。
1. Error Message
" Error Message : エラーメッセージ “
検索ページ(Search API)をクリックすると
" The website encountered an unexpected error. Try again later. "
のエラーが出てしまい。検索画面が開きません。
ログを確認すると以下の内容になっています。
Drupal\Core\Render\Component\Exception\InvalidComponentException: [civictheme:list/rows_above[0]] Object value found, but a string is required. in Drupal\Core\Theme\Component\ComponentValidator->validateProps() (line 243 of /home/xx123456/yoursite.com/public_html/yoursite.com/your-project/web/core/lib/Drupal/Core/Theme/Component/ComponentValidator.php).
エラーメッセージに表示されたComponentValidator.phpの243行目近辺を見てみます。
// Dismiss type errors if the prop received a render array.
$errors = array_filter(
$this->validator->getErrors(),
function (array $error) use ($context): bool {
// Support 5.0 ($error['constraint']) and 6.0
// ($error['constraint']['name']) at the same time.
if (($error['constraint']['name'] ?? $error['constraint'] ?? '') !== 'type') {
return TRUE;
}
return !Element::isRenderArray($context[$error['property']] ?? NULL);
}
);
if (empty($errors)) {
return TRUE;
}
$message_parts = array_map(
static function (array $error) use ($component_id, $context): string {
// We check the error message instead of values and definitions here
// because it's hard to access both given the possible complexity of a
// schema. Since this is a small non critical DX improvement error
// message checking should be sufficient.
if (str_contains($error['message'], 'NULL value found, but a ')) {
$error['message'] .= '. This may be because the property is empty instead of having data present. If possible fix the source data, use the |default() twig filter, or update the schema to allow multiple types.';
}
// If the property value has been set, print it out for easier
// debugging.
if (isset($context[$error['property']]) && \is_scalar($context[$error['property']])) {
$error['message'] .= \sprintf('. The provided value is: "%s"', $context[$error['property']]);
}
// 243行目は以下の行になります。
return sprintf('[%s/%s] %s.', $component_id, $error['property'], $error['message']);
},
$errors
);
$message = implode("\n", $message_parts);
throw new InvalidComponentException($message);
}
// Dismiss type errors if the prop received a render array.
// プロパティにレンダリング配列が渡された場合は、型エラーを無視する。
DrupalのSingle Directory Components (SDC) で定義されているコンポーネント(CivicThemeの list コンポーネント)に対して、「文字列(string)」を渡すべきプロパティ(rows_above)に「オブジェクトなど(文字列以外とレンダリング配列以外)」を渡してしまっているために発生しています。
2. Countermeasures
” Countermeasures : 対応策 “
状況をもう少し、考えてみます。
- ComponentValidator.phpのチェックポイントである、レンダー(html出力と単純化して考えます)に対する文字列の引き渡しと配列の引き渡しのみをパスし、それ以外のオブジェクトなどをエラーとして除外する、というチェック項目に、オブジェクトなどの文字列以外の値が渡されている可能性があります。そのためチェックにかかりエラーを出していると考えられます。
- 実際に不具合が出ているのはSearch APIのレンダー(ページ表示)のみなので、Search APIないし、Search APIにデータを渡すCivic Themeのコンポーネントで起きていると考えられます。
セオリーからすれば、上記を考慮し、該当するTwigやPHPのプロセスを特定し文字列ないし配列に変換(原因箇所の特定と理由をしっかり突き止めることが前提)する対応が考えられます。
しかし今回のエラーが発生した状況は
- Drupal 11.4.0のアップデート直後であること
- Drupal 11.4.0はSymfonyの厳格なチェックが強化されたことで、前回記事で触れたエラーを出してしまっていること
- テーマであるCivic ThemeやモジュールであるSeach APIのDrupal 11.4.0との依存関係がクリアされていない可能性があること
があるので、今回、エラー修復として行う、TwigやPHPの訂正が、後のアップデートで変更され、逆にエラーや不具合の原因になってしまう可能性があります。
3. Illegal moves
” Illegal moves : 反則技 “
目の前のエラーの修復は、必須であり(画面が真っ白でエラー表示)早急に対応する必要があります。上記の正攻法で、エラーを特定し、構文の変更を行うのは、現実として結構時間がかかります。
上記で述べましたが、今回のエラーには Drupal Core > Civic Theme > Search APIと三者が絡んでおり、元にあるDrupal Coreが、過去に比べ、チェック項目を厳格にしたことで、テーマ開発者や、モジュール開発者の対応が追いついていない可能性も考えられます。
私のような個人が自身の環境で、現時点で考えられる正攻法で、正しい構文に訂正しエラー修復するという対応が、Drupal開発の過渡期である現時点で正しい対応かと考えると疑問が生じます。
恐らく、後々には、Drupal開発陣の不具合対応や、テーマ開発者、モジュール開発者の不具合対応が進み、私が行う応急処置的な対応ではない、恒久的な対応を済ませたアップデートが配布されることは間違いありません。
そう考えると、全く別の対応が頭に浮かびます。
3-1. All-Purpose Tool
” All-Purpose Tool : 万能ツール “
今回のエラーは、平たく言えば、レンダリング(ページ生成)に渡すデータは、文字列と、文字列の配列のみというルールが設定されており、他の要素(オブジェクトなど)が渡されてしまった為に出てしまっているエラーになります。
そのレンダリングの影響がSearch APIの生成するページにのみ出ています。プログラムの内部処理というより、処理されたデータの最終出力であり、影響は生成されるページにのみ影響するエラーです。
エラーの原因は、Search APIのレンダリング(ページ生成)には、テキスト(string)や配列(Array)以外のオブジェクトは通さないというルールに、許可されていないオブジェクトが渡されている(と判断する)ことで発生しているエラーになります。
そもそも、このチェックが必要か?と考えると非常に簡単で即効性のある解決策が浮かびます。
反則技ですが今回のエラーに対し以下の対応がベストではと考え実行します。
// 反則技
ComponentValidator.php
206行目付近、// Dismiss type...の上に以下を追記します。
-----------------------------------------------------
return TRUE; // 何が来てもエラーをすべてチャラにする
-----------------------------------------------------
// Dismiss type errors if the prop received a render array.
$errors = array_filter(
$this->validator->getErrors(),
...
return TRUE; をチェックプロセスの前に挟むことで、エラーの原因となっている、データの受け渡しのチェックを外してしまいます。このことで、エラーの原因となっているtwigやPHPの構文を探し訂正することなくエラーが解決します。
PHPの構文を変更するので、保存したら、キャッシュのクリアをします。
$ drush cr
以上で、
" The website encountered an unexpected error. Try again later. "
が消え、Search APIの検索画面が表示されます。
3-2. First Aid
” Firsr Aid : 応急処置 “
今回の対応は、Drupal 11.4.x系で導入されたSymfonyの厳格化されたルールに、テーマやモジュールの対応が追いついていない(私は、Drupal 11.4.0はリリース直後にアップデートしています)、検証と対応はしているが、ユーザーの環境によっては不具合が生じるといった、Drupalコアプログラムのマイナーやメジャーアップデートのドラスティックな変更時に起きる不具合に対しての応急処置的な対応になります。
- 不具合の原因が一時的で恒久的なものではないという予測
- 即効性があり、すぐ元に戻せる対応
- 影響範囲が軽微であること(今回はSearch APIのページ生成のみの影響)
以上の条件が揃っていたので、反則技とも言える、応急処置で対応しています。
今回の対応は、開発者が、開発中に生じる軽微なエラーをパスして、開発を進めるようなケースで用いられる方法でもあり、もう少しスマートに行うのであれば以下のような方法も考えられます。
※ ymlの記述は検証していないので、動作や影響は自己責任でお願いします。
web/sites/development.services.yml
以下の記述 falseでvalidateそのものを無効にする
core.services:
ComponentValidator:
validate_props: false
今回の対応は、Drupal 11.4.x(Drupal 12への布石と考えています)のアップデートで起きた一時的なものと判断しての応急処置であり、私の利用環境において現時点での最善策としての対応になります。他の Drupal > Civic Theme > Search APIを使う方にとって、環境や利用状況も異なるので、もし同じような対応を行う場合は、事前検証を行い、影響が出ないことを確認してから自己責任において実行してください。
In Closing
Xserverの新サーバーへの移転で、Maria DBのアップデートからDrupal 10.x > Drupal 11.xにアップデートを行い、同じタイミングで、Drupal 11.3.x > Drupal 11.4.0 へのアップデートをした中で、起きた不具合をまとめています。
Drupal 11.4.0 のアップデートで出たエラーの対策し、修復完了後の確認で出ていたエラーが今回記事にしたSearch APIのエラーになります。Civic Themeのパッケージとして選択されたモジュールであり、関連性や依存関係を正確に把握することが難しい状況でのエラーであり、状況はレンダリング(ページ生成)のみの影響と軽微であったので、応急処置にて対応しています。
Drupalも多層化したプラットフォームであり、PHP > Symfony > Drupalと上層から下層へとアップデートが影響します。昨今AIの普及で、重大なセキュリティホールが見つかったり、攻撃ツールの高性能化が進むことで、各プラットフォームのアップデートの緊急性や頻度が上がっています。
私は開発者ではないので、全てをリアルタイムで完璧に対処することは難しいのですが、状況を把握し、セキュリティ対策など他人に迷惑のかからない形での優先順位をしっかり判断し実践することは、OSSのボランティアで開発されるプラットフォームを使わせていただいていることに対する最低限の敬意であると考えています。