@catch ディレクティブ
@catch
ディレクティブは、Relay クエリ/フラグメント/ミューテーションのフィールドに追加して、ランタイムでの例外と予期しない値の処理方法を宣言できます。@catch
を使用すると、Relay は null 値(以前のデフォルトの動作)ではなく、レスポンスデータ内の例外を提供できます。
GraphQL レスポンスにフィールドエラーが含まれている場合、Relay はエラーを探し、そのフィールドまたは親フィールドに@catch
ディレクティブが存在する場合は、{ok: true, value: "あなたの値"}
または{ok: false, errors: [...]}
で応答します。
エラーが発生したフィールドに直接@catch
エラーがキャッチされた場合、エラーはそのフィールドに提供されます。例を以下に示します。
query MyQuery {
viewer {
name @catch
age
}
}
name
にエラーが含まれている場合、次のようにname
フィールドのレスポンスデータにエラーが提供されます。
{
viewer: {
name: {
ok: false,
errors: [
{
message: "Couldn't get name",
path: ['viewer', 'name']
}
]
}
age: 39
}
}
ただし、フィールドの祖先に@catch
が存在する場合は、エラーがそこへバブルアップします。
query MyQuery {
viewer @catch {
name
age
}
}
{
viewer: {
ok: false,
errors: [
{
message: "Couldn't get name",
path: ['viewer', 'name']
}
]
}
}
@catch
でキャッチできるもの
ペイロードエラー
ペイロードエラーは、特定のフィールドのレスポンスを実行中にサーバー側で例外が発生した結果として発生するエラーです。この場合、GraphQL サーバーは値が存在するべき場所に null 値を提供し、別の errors オブジェクトを提供します。
フィールドで@catch
を使用すると、Relay はこれらのエラーをインラインで提供するため、処理が容易になり、非表示になることがなくなります。
もう1つの大きな副作用として、フィールドがNULL許容の場合、null が例外の結果であるか真の null であるかがわかるようになります。これは、形状に値がnull
の{ok: true}
、または実際のエラーを含む{ok: false}
が含まれるためです。
@catchの下の@required(action: THROW)
@catch
を含む祖先を持つ@required(action: THROW)
がある場合、例外をスローする代わりに、@required
エラーはバブルアップし、通常のエラーと同じ方法で提供されます。例を以下に示します。
query MyQuery {
viewer @catch {
name @required(action: THROW)
age
}
}
{
viewer: {
ok: false,
errors: [
{
message: "Relay: Missing @required value at path 'viewer.name' in 'MyQuery'.",
}
]
}
}
レスポンス内のデータの欠落
Relay でデータの欠落が発生する可能性のある例を以下に示します。
フィールドに値があることが期待され、そのフィールドが未定義の場合、そのフィールドは「データが欠落している」と見なされます。これも予期しない状態であり、祖先に@catch
がある場合、次のようにキャッチされます。
{
viewer: {
ok: false,
errors: [
{
message: "Relay: Missing data for one or more fields in MyQuery",
}
]
}
}
@catch
は@throwOnFieldError
とどのように連携しますか?
@throwOnFieldError
を使用すると、フィールドエラーが発生したときにフィールドがJavaScript例外をスローできます。@catch
を使用すると、この場合、JavaScript例外を発生させないようにRelayに指示します。代わりに、上記と同じ動作とルール(親フィールドへのバブルアップを含む)で、エラーをデータオブジェクトに提供するように要求します。
@throwOnFieldError
なしで@catch
を使用することもできます。それでも、データオブジェクトにエラーが提供されます。しかし、@catch
の下にない他のフィールドは、@throwOnFieldError
がないため、引き続きスローされません。
@throwOnFieldError
の詳細については、こちらをご覧ください。
@catch
の引数
to: RESULT (デフォルト)
@catch(to: RESULT)
は、エラーを含む同じフィールドまたは子フィールドに対してエラーをインラインで提供するという上記の動作を有効にします。これはデフォルトの引数であるため、@catch
または@catch(to: RESULT)
のどちらかを記述しても、動作は同じになります。
to: NULL
@catch(to: NULL)
は、@catch
が使用可能になる前に存在していたものとまったく同じ動作を提供します。エラーが含まれている場合、フィールドは null になります。