結論
WP_Error は、エラーコード、メッセージ、補足データを持つ、WordPress 共通のエラーオブジェクトです。関数が失敗したときに false や 0 の代わりに返され、受け取った側は is_wp_error() で必ず判定します。
押さえる点は4つです。
if ( $result )では判定できない。WP_Error オブジェクトは真と評価される- 自作関数でも、失敗は WP_Error を返し、成功時と型を分ける
- 複数のエラーは add() で積み、has_errors() で確認してから返す
- REST API では、第3引数の data に status を入れると HTTP ステータスになる
原因・仕組み
WP_Error はクラスなので、返り値が成功した値か失敗かは型で区別します。公式リファレンスでも、返り値が WP_Error かどうかを調べるために is_wp_error() を使うと説明されています。
主なメソッドは次のとおりです。
| メソッド | 役割 |
|---|---|
| add( $code, $message, $data ) | エラーを追加する |
| get_error_code() | 最初のエラーコードを返す |
| get_error_codes() | すべてのエラーコードを配列で返す |
| get_error_message( $code ) | メッセージを返す(コード省略で最初のもの) |
| get_error_messages() | すべてのメッセージを配列で返す |
| get_error_data( $code ) | 補足データを返す |
| has_errors() | エラーが1件以上あるか |
| add_data( $data, $code ) | 補足データを追加・置換する |
| merge_from( $other ) | 別の WP_Error を取り込む |
手順(サンプルコード)
バリデーション関数
function ks_validate( $data ) {
$errors = new WP_Error();
if ( empty( $data['name'] ) ) {
$errors->add( 'missing_name', '名前は必須です。', array( 'field' => 'name' ) );
}
if ( ! isset( $data['age'] ) || ! is_numeric( $data['age'] ) ) {
$errors->add( 'invalid_age', '年齢は数値で指定してください。', array( 'field' => 'age' ) );
}
if ( $errors->has_errors() ) {
return $errors;
}
return array(
'name' => sanitize_text_field( $data['name'] ),
'age' => (int) $data['age'],
);
}
呼び出し側
$result = ks_validate( $_POST ); // 実際には nonce と権限の確認を先に行う
if ( is_wp_error( $result ) ) {
foreach ( $result->get_error_messages() as $message ) {
echo '<p class="error">' . esc_html( $message ) . '</p>';
}
return;
}
// 成功時は $result を使う
REST API で返す
return new WP_Error( 'ks_forbidden', '権限がありません。', array( 'status' => 403 ) );
動作確認(検証環境と結果)
WordPress 7.1.2(日本語)、PHP 8.2.12(testswp-error-handling-is-wp-error.md に全文)。
| 確認内容 | 結果 |
|---|---|
| 空の配列で ks_validate() | is_wp_error() が true |
if ( $r ) による判定 |
真になる(WP_Error は真と評価される) |
| get_error_codes() | missing_name, invalid_age |
| get_error_code() | missing_name(最初のもの) |
| get_error_message() | 名前は必須です。 |
| get_error_message(‘invalid_age’) | 年齢は数値で指定してください。 |
| get_error_data(‘invalid_age’) | {“field”:”age”} |
| 正しい入力 | 配列が返り、is_wp_error() は false |
| add_data() で2つ目のデータを追加 | get_error_data() は後のデータ(’data A2’)を返した。get_all_error_data() では ‘data A1’ と ‘data A2’ の両方が取得できた |
| merge_from() | コードが a, b に統合された |
| wp_insert_post( 空, true ) | WP_Error(コード empty_content、メッセージ「本文、タイトル、抜粋が空欄です。」) |
| wp_remote_get(存在しないドメイン) | WP_Error(コード http_request_failed) |
| get_term( 999999, ‘category’ ) | NULL(WP_Error ではない) |
| get_term( 999999, 存在しないタクソノミー ) | WP_Error(コード invalid_taxonomy) |
| REST: rest_convert_error_to_response() | ステータス 403、data に code と message |
get_term() のように、同じ関数でも「見つからない」は NULL、「引数が不正」は WP_Error と、返り値が分かれるものがあります。公式リファレンスで戻り値の型を確認してください。
WP_Error の扱い方の注意点
- エラーメッセージを画面に出すときは、esc_html() などでエスケープします。メッセージにユーザー入力を含める場合は特に注意してください。
- エラーコードは、プレフィックス付き(ks_ など)にして、他のプラグインと衝突しないようにします。
- ユーザーに見せるメッセージと、ログ用の詳細情報(データ)を分けて持たせると、再利用しやすくなります。
- add_data() で同じコードにデータを追加すると、get_error_data() が返すのは最新のデータだけです。WordPress 5.6 以降は、それ以前のデータも内部に残り、get_all_error_data() で取り出せます。複数の情報を確実に1回で渡したいときは、配列にまとめて渡すと扱いやすくなります。
- 多言語化するメッセージは
__()で包みます。
WP_Error の扱い方でよくあるミス
if ( ! $result )で判定して、WP_Error をそのまま通してしまう。- wp_insert_post() に第2引数 true を渡さず、失敗が 0 で返ってきて原因が分からない。
- wp_remote_get() の戻りに wp_remote_retrieve_body() をかけ、WP_Error のまま空文字になる。
- WP_Error を echo してしまう(オブジェクトなのでエラーになる)。
WP_Error の扱い方のチェックリスト
- 外部の関数を呼んだ戻り値を is_wp_error() で判定したか。
- 自作関数の失敗は WP_Error で返しているか。
- REST のエラーに status を付けたか。
- メッセージを出力するとき、エスケープしているか。
- ログに残す情報と、画面に出す情報を分けたか。
WP_Error の扱い方のFAQ(よくある質問)
Q. WP_Error を例外(try/catch)に置き換えられますか。
A. WordPress のコア関数は WP_Error を返す設計なので、混在させると呼び出し側が複雑になります。自作コードでは WP_Error に統一するのが無難です。
Q. メッセージの取り出しで空になります。
A. エラーコードを指定していて、そのコードが存在しない可能性があります。get_error_codes() で確認してください。
Q. is_wp_error() とクラスの instanceof の違いは。
A. 機能は同じで、is_wp_error() は WordPress の関数として用意されています。どちらでも構いませんが、プラグインの統一性のため is_wp_error() を使う例が多いです(is_wp_error() の使い方|説明・引数・注意点)。
筆者の見解(WP_Error の扱い方)
私見では、WP_Error を扱うコードの品質は、呼び出し側の判定漏れで決まると考えます。関数を呼んだら次の行で is_wp_error() を書く、という習慣をつけると、リリース後の原因不明の不具合が減ります。自作関数でも、false を返す設計より、理由を持てる WP_Error のほうが、のちの調査が楽です。
WP_Error の扱い方の関連項目
- WP_Error クラスの使い方|説明・引数・注意点
- is_wp_error() の使い方|説明・引数・注意点
- wp_insert_post() の使い方|説明・引数・注意点
- WP_REST_Request クラスの使い方|説明・引数・注意点
- wp_remote_get() の使い方|説明・引数・注意点

