LoginSignup
2
2

kintoneカスタマイズでtry/catchを使おう

Last updated at Posted at 2024-02-16

はじめに

皆さんこんにちは。サイボウズ株式会社テクニカルトレーナーのTeruです。
今回はkintoneカスタマイズにおけるtry/catchの使い方を考えていきましょう!

try/catchの基本

そもそも、try/catchは例外が発生した場合に例外を処理するために使用します。

try {
 実行する処理
} catch(e) {
 try文で例外が発生した場合に実行される処理
}

例外とは、kintoneカスタマイズにおいては多くの場合 REST API の実行に失敗した場合のことです。

サンプル

例えば、アプリ番号:1 レコード番号:1のレコードを取得する場合は下記のようにtry/catchを使用します。

try {
  // レコード取得処理
  await kintone.api('/k/v1/record', 'GET', { app: 1, id: 1 });
} catch (e) {
  // レコード取得に失敗した場合の処理
  console.error(e);
}

この取得処理でエラーが発生するのは、次のようなケースです。

  • アプリが存在しない
  • レコードが存在しない
  • ネットワークエラー

仮にアプリが存在しなければ、console.error(e)はこのようなエラーを表示します。
{code: 'GAIA_AP01', id: '8BwNVgSl5Z0XNrXaZbZI', message: '指定したアプリ(id: 1)が見つかりません。削除されている可能性があります。'}

ちなみにcatch(e)e部分は自由に命名できますし、catch内で使用しなければ省略することもできます。

省略する場合のサンプル

try {
  // レコード取得処理
  await kintone.api('/k/v1/record', 'GET', { app: 1, id: 1 });
} catch {
  // レコード取得に失敗した場合の処理
  console.error('取得に失敗しました');
}

複数の処理の扱い方

次に、複数の REST API を実行する場合のtry/catchについて扱っていきます。
例えば次のようなケースです。

  • アプリ番号:1 レコード番号:1のレコードを取得する
  • 取得したレコードの値を用いて、アプリ番号:2にレコードを登録する

try/catchでひとまとめにするパターン

try {
  // レコード取得処理
  const resp = await kintone.api('/k/v1/record', 'GET', { app: 1, id: 1 });
  // レコード登録処理
  const params = {
    app: 2,
    record: {
      氏名: {
        value: resp.record.氏名.value,
      },
    },
  };
  await kintone.api('/k/v1/record', 'POST', params);
} catch (e) {
  // 失敗した場合の処理
  console.error(e);
}

この場合は、取得処理・登録処理のどちらかにエラーが発生した瞬間にcatchへ飛びます。
処理が正常に終了しなかったことをユーザーに対してアラートを表示したり、コンソールにエラーを表示することができます。

しかし、このコードではどちらでエラーが発生したのかはcatch内で判別ができません。
「取得に失敗しました」や「登録に失敗しました」といったエラー文の使い分けができないことになります。
では、それぞれにtry/catchを設定すれば良いのでは?と考える人もいるかもしれません。

try/catchを個別に設定するパターン(動作しません)

try {
  // レコード取得処理
  const resp = await kintone.api('/k/v1/record', 'GET', { app: 1, id: 1 });
} catch (e) {
  // レコード取得に失敗した場合の処理
  console.error(e);
}

try {
  // レコード登録処理
  const params = {
    app: 2,
    record: {
      氏名: {
        value: resp.record.氏名.value,
      },
    },
  };
  await kintone.api('/k/v1/record', 'POST', params);
} catch (e) {
  // レコード登録に失敗した場合の処理
  console.error(e);
}

今回のコードは動きません。
try{}でスコープ(=変数がアクセスできる範囲)を作り出しています。
スコープ内で宣言された変数は外からアクセスすることができません。
よって、登録処理側でrespにアクセスすることができないわけですね。
まあ一応解決策としてrespを外でletを使って先に宣言してしまう方法もあるのですが、エラー処理のためにエラーが発生する要因を作ることになりかねないので非推奨です。

ではどのようにすればいいでしょうか。

await/catchを使うパターン

// レコード取得処理
const resp = await kintone.api('/k/v1/record', 'GET', { app: 1, id: 1 }).catch((e) => console.error('レコード取得失敗',e));

// レコード登録処理
const params = {
app: 2,
record: {
  氏名: {
    value: resp.record.氏名.value,
  },
},
};
await kintone.api('/k/v1/record', 'POST', params).catch((e) => console.error('レコード登録失敗', e));

Promiseチェーンを活用してエラー処理を行うこともできるわけです。
try/catchでひとまとめにするパターンが楽でいいですけどね。

例外処理を発生させたいとき

kintoneカスタマイズではcatchに飛ぶだろう・・・と想定していることがcatchに飛ばないことがあります。
それは次のようなケースです。

  • アプリ番号:1の最新の顧客番号を持つレコードを取得する
  • 取得した顧客番号に+1した値を顧客番号にセットしてアプリ番号:1にレコードを登録する

この処理を行う時、もしレコードが一つもなかったらcatchに飛ぶだろう・・・と思いませんか?
いいえ、飛びません。

レコードが一つもないのは、絞り込みで0件表示の時と同じ状態なのでエラーではないのです。
取得処理自体は成功している扱いになります。

こういう場合に使うのがthrowです。例外を強制的に発生させることができます。

try {
  // レコード取得処理
  const resp = await kintone.api('/k/v1/record', 'GET', {
    app: 283,
    query: 'order by 顧客番号 desc limit 1',
  });

  // レコードが0件の場合は例外を発生させる
  if (resp.records.length === 0) throw new Error('レコードが存在しません');

  // レコード登録処理
  const params = {
    app: 285,
    record: {
      顧客番号: {
        value: resp.records[0].顧客番号.value + 1,
      },
    },
  };
  await kintone.api('/k/v1/record', 'POST', params);
} catch (e) {
  console.error(e);
}

このようにthrowすることでcatchに強制的に飛ばすことができます。

まとめ

  • REST API と try/catchはセットで使いましょう
  • 個別にエラー処理をしたい場合は await/catchを使いましょう
  • 例外を発生させたいときは throw を使いましょう
2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2