Promise処理を中断した際と思われるエラーについて

お世話になっております。

先日こちらで質問いたしました、金額表示欄と関連レコードに物品名と金額を表示するアプリで、レコード詳細画面を開いた際に関連レコードの金額を集計して金額表示に表示する機能について、

動作は作成できたのですが、気になる現象が発生しましたので、そちらをお伺いしたく、質問させて頂きます。

前回の質問 : https://developer.cybozu.io/hc/ja/community/posts/10523344366361

・気になる点

関連レコードのデータを取得し、その金額を計算するにあたって、Promiseを用いてデータが取得できたら次、と進める形にしました。

その途中で、保存されている合計金額と計算した合計金額が同じだったら処理を中断するという動作にしたくて、

return resolve();

で途中で終了する処理を入れたのですが、この処理に入るとエラーと判定されるようなのです(ソース上のalert(‘エラー’);のところに行ってしまう)

しかし、ディベロッパーツールでも詳細が表示されておりませんでした。

この現象は正常なものなのでしょうか。それとも処理に問題があってreturn resolve();を行うとエラーになってしまうのでしょうか。

お力を貸していただきたいです。よろしくお願いいたします。

(() => {
  'use strict';
  //レコード詳細画面表示時に実績集計
  kintone.events.on(['app.record.detail.show'],(event) => {

    const rec = kintone.app.record;
  const query = '製番="' + event.record['管理コード'].value +'"';
  var dataChange  = 0; //レコード更新判定
  var beforeActual = event.record['仕入品_実績合計'].value; //レコードに表示される仕入金額1
  var beforeStock = event.record['在庫_実績合計'].value; //レコードに表示される在庫の出庫金額
  var NewActual; //関連レコードから計算した仕入金額
  var NewStock;     //関連レコードから計算した在庫の出庫金額
    var thisApp = kintone.app.getId();
    var thisID = kintone.app.record.getId();
// 関連レコード先の判別1
    const params = {
      'app': 69,  //仕入れ管理
      'query': query
    };
// 関連レコード先の判別2
    const params2 = {
      'app': 70,  //在庫入出庫履歴
      'query': query
    };

    //仕入実績計算
    return kintone.api(kintone.api.url('/k/v1/records', true), 'GET', params).then((resp1) => {
      var total = 0;
      //取得したデータから仕入実績分計算
      for (var i = 0; i < resp1.records.length; i++) {
        total += parseFloat(resp1.records[i].数値_7.value);
      }
    NewActual = total;
      //在庫からの実績分データ取得
      return kintone.api(kintone.api.url('/k/v1/records', true), 'GET', params2);
    }).then((resp2) => {
      //在庫からの取得データで計算
      var total = 0;
      if(resp2.records.length !== 0){
        for (var i = 0; i < resp2.records.length; i++) {
          total += parseFloat(resp2.records[i].出庫金額.value);
      }
      NewStock = total;
      }
//レコードに保存されている合計金額と異なっていたらレコード更新予約
      if(NewActual != beforeActual){
        dataChange = 1;
      }
      if(NewStock != beforeStock){
        dataChange = 1;
      }
      
    //仕入、在庫出庫の両方のレコード数が0ならこの後の処理はしない
      if(resp2.records.length === 0){
        if(resp1.records.length === 0){
          return resolve();
        }
      }
      
    //全体の合計算出
        var AllTotal = NewActual + NewStock;
       // resolve(event);
    //レコード更新の予約がされてなければ中断
      if(dataChange === 0)
      {
        return resolve();
      }
      const body = {
        'app': thisApp,
        "id": thisID,
        'record': {
        '管理コード':{
          'value':event.record['管理コード'].value
          },
          '仕入品_実績合計': {
            'value': NewActual
          },
          '在庫_実績合計':{
            'value': NewStock
          },
          '実績合計':{
            'value':AllTotal
          }
        }
      };
      alert('実績の更新が確認されたため、再計算を行います');
//レコード更新の処理
      return kintone.api(kintone.api.url('/k/v1/record.json', true), 'PUT', body);
      }).then((resp3) => {
//画面のリロードを1回だけ行う
        if (window.name != "Cmp") {
        location.reload();
        window.name = "Cmp";
        } else {
        window.name = "";
        }
        return;
      }).catch(() => {
    
      alert('エラー');
      return event;
    });
  });
})();

Sei_EL様

promiseの返り値としてresolveを設定していないからかな?とおもいます。
(kintone promiseは暗黙的にresolveをreturnするだけだったと思います)
もし、“空"のresolveを返したいなら、ただ単にreturn “”;でもよいのかな、と思います。
(resp3に”"を返す)

 

エラーとなっている原因は、resolve() が未定義の関数になっているためです。

記述的には Promise.resolve() が正解ですが、この処理の場合スキップの戻り値として Promise を返す必要はないので、TOさんの仰る通り return; で何も値を返さず、次の then ブロック内で resp3 に値(*1)があるかどうかで条件分岐すれば良いと思います。

*1 前の then ブロックで return した値、もしくは Promise で解決した値が入ります

        //全体の合計算出
        var AllTotal = NewActual + NewStock;
        // resolve(event);
        //レコード更新の予約がされてなければ中断
        if (dataChange === 0) {
          return;
        }
      // ...中略...
      })
      .then((resp3) => {
        if (!resp3) {
         // 後続のイベントが処理ができるように event を返す
         return event;
        }

        //画面のリロードを1回だけ行う
        if (window.name != 'Cmp') {
          location.reload();
          window.name = 'Cmp';
        } else {
          window.name = '';
        }
        return;
      })
      .catch(() => {
        alert('エラー');
        return event;
    });

ちなみにコンソールにエラーが表示されない原因は、catch ブロックを定義しているとコンソールまでエラーが伝達しないからです。catch ブロックを定義してコンソールでエラーを確認したい場合は、以下のように記述します。

    .catch((error) => {
      console.error(error);
        return event;
    });

 

 

TO様

川村様

コメントありがとうございます。

いただいたコメントを元にreturn resolve();周りの処理をしたところ、エラーが無く動作しました。

また、コンソールへのエラー表示の方も入れたところ、

if(resp1.records.length ===0){

の部分でもエラーが発生していたことが分かり、修正することができました。

(resp2の中で処理していたため、resp1が未定義の状態になっていました)

お二人ともありがとうございました。

このトピックはベストアンサーに選ばれた返信から 3 日が経過したので自動的にクローズされました。新たに返信することはできません。