JavaScriptアクションのエラーハンドリング
エラーの返し方の基本
JavaScriptアクションは、正常終了する場合に return
を、異常終了する場合に throw
を使って実行結果を返すことができます。
例えば、アクションへの入力値が想定しない値だった場合に、処理を打ち切りたいケースがあるでしょう。
その場合、Errorを throw
することで、アクションの実行結果を失敗として返せます。
以下は、ユーザー取得アクションを実行し、ユーザーが見つからなかった場合にエラーを throw
するJavaScriptアクションの例です。
import { executeAction } from "@basemachina/action";
// 指定されたユーザーの投稿を作成するアクション
export default async ({ userId, post }) => {
const getUserResults = await executeAction("getUser", { userId });
// 不正な入力だったら、処理を中断する
if (!getUserResults[0].success.length < 1) {
throw new Error("ユーザーが見つかりませんでした");
}
// ユーザーが見つかった場合は、投稿を作成する
await executeAction("createPost", { userId, post });
};
このとき、throw
されたエラーは以下のように実行結果に表示されます。
アクションの結果加工スクリプトや、executeAction関数の結果としては、failure
キーに同様の文字列が設定された形で取得できます。
一般的なユースケースでは、文字情報としてエラーの内容を伝達できれば問題ありませんが、場合によっては、任意の形式のObjectとして結果を返したいこともあるでしょう。 そうしたケースでは、ResultErrorを活用できます。
ジョブからエラーを返した場合の挙動
ジョブとして実行したJavaScriptアクションからエラーが throw
された場合は、ステータスが「実行完了」ではなく「エラー」となります。
「エラー」で終了したジョブの結果を閲覧すると、通常のアクション実行時と同じ形式でエラー情報が表示されます。
組み込み関数のエラー
JavaScriptアクションから呼び出す組み込み関数は、エラーを throw
することがあります。
例えば、 executeAction
関数を呼び出すときに、引数や、ユーザーの実行権限に問題がある場合にエラーが発生します。
また、ネットワークの問題などの、システム要因のエラーが発生することもあります。
基本的に、組み込み関数から発生するエラーは、その原因についての情報を含める形で throw
されるため、明示的にハンドリングせずとも、エラー原因の特定に利用できます。
そのうえで、リトライ処理の実装などのためにエラーハンドリングを明示的に行ないたい場合は、組み込み関数の呼び出しを try-catch
のブロックで囲んでください。
ResultError
ResultError
は、throw
することで、エラーの内容を任意の形式のObjectとして返すことができるクラスです。
文字情報だけでは情報の視認性に欠ける場合や、別のJavaScriptアクションや加工スクリプト、ビューなどから結果を扱いにくいようなケースで活用できます。
本ページ冒頭の例で、ユーザーの存在有無による判定を行なっていましたが、これに加えてユーザーの属性による判定を加えるケースについて考えてみましょう。
下記の例では、ユーザーのステータスと、年齢による判定を行なっています。
import { executeAction } from "@basemachina/action";
const isValidUser = (user) => {
if (user.status !== "ACTIVE") {
return false;
}
if (user.age < 20) {
return false;
}
return true;
};
// 指定されたユーザーの投稿を作成するアクション
export default async ({ userId, post }) => {
const getUserResults = await executeAction("getUser", { userId });
if (!getUserResults[0].success.length < 1) {
throw new Error("ユーザーが見つかりませんでした");
}
const user = getUserResults[0].success[0];
if (!isValidUser(user)) {
throw new Error("ユーザーが有効ではありません");
}
// ...
await executeAction("createPost", { userId, post });
};
ここで、「ユーザーが有効ではありません」という文字列で結果を返していますが、「ステータス」か、「年齢」のどちらに問題があったのか読み取ることができません。
このような場合に、ResultError
を使うことで、より詳細な情報をエラーに追加できます。
import { executeAction, ResultError } from "@basemachina/action";
// ...
export default async ({ userId, post }) => {
// ...
if (!isValidUser(user)) {
throw new ResultError({
message: "ユーザーが有効ではありません",
user: {
status: user.status,
age: user.age,
},
});
}
このとき、アクションの実行結果の表示は次のようになります。
詳細な情報が表示されたことで、ユーザーのステータスに問題があったことを突き止めるのが簡単になりました。
エラーの詳細を含む文字列を組み立ててErrorを throw
するよりも、ResultErrorを使った方が手軽にエラーに詳細情報を付加できます。
アクションの結果加工スクリプトや、executeAction関数の結果としては、failure
キーにResultErrorのコンストラクタへ渡したObjectが設定された形で取得できます。
ジョブの実行に失敗したときの詳細な状況を記録するなどといった、デバッグ目的にも活用できます。
ResultErrorを使って返すことのできる値の種類は、基本的にJavaScriptアクション成功時に返すことのできる値の種類と同じですが、現在 File
および Blob
はサポートされていません。