質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.97%

エラーが出た時にもう一度関数を実行する処理を施したいです。

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,958

Kazuki74

score 6

 前提・実現したいこと

GAS(javascript)を用いて、FacebookのAPIからスプレッドシートにデータを引っ張って来る処理を実装しようとしています。
実装には成功したのですが、時々GETリクエストでエラーが出てしまいます。
トリガーを設定し毎日定時に確実に処理を実行したいため、エラーが出た時にもう一度関数を実行する処理を施したいです。
下記ソースコード下部のkpiFunctionをエラー時に再実行したいです。

 発生している問題・エラーメッセージ

下記ソースコードの"UrlFetchApp.fetch"で引っかかります。3か所ほどありますが毎回同じ場所でエラーが出るわけではありません。

 該当のソースコード

Google Apps Script

var ACCESS_TOKEN = "";

function getReportByHttpRequest(today, fields, campaign_id) {
  var payload = 
      {
        "time_range" : "{'since':'" + today + "','until':'" + today + "'}",
        "fields" : fields,
        "access_token" : ACCESS_TOKEN
      };

  var options =
      {
        "method" : "POST",
        "payload" : payload
      };
  return UrlFetchApp.fetch("https://graph.facebook.com/v2.12/" + CL_CAMPAIGN_ID + "/insights?access_token=" + ACCESS_TOKEN, options);
}

function getProgressByHttpRequest(report_run_id){
  var url = "https://graph.facebook.com/v2.12/" + report_run_id + "?access_token=" + ACCESS_TOKEN;
  var response = UrlFetchApp.fetch(url);
  var json = JSON.parse(response);
  return json["async_percent_completion"];
}

function getFacebookReport(response) {
  var json = JSON.parse(response);
  var report_run_id = json["report_run_id"];
  Logger.log(report_run_id);

  var progress_percentage = getProgressByHttpRequest(report_run_id);
  Logger.log(progress_percentage);

  while (progress_percentage < 100) {
    Utilities.sleep(10000);
    progress_percentage = getProgressByHttpRequest(report_run_id);
    Logger.log(progress_percentage);
  }

  var url = "https://graph.facebook.com/v2.12/" + report_run_id + "/insights?access_token=" + ACCESS_TOKEN;
  var response = UrlFetchApp.fetch(url);
  json = JSON.parse(response);
  return json;
}

  //  キャンペーンID
  var CL_CAMPAIGN_ID = "XXXXXXXXXXXXXXXXXX";

  // スプレッドシート取得
 var spreadsheet = SpreadsheetApp.openById('XXXXXXXXXXXX');
  //  スプレッドシート参照
  var cl_sheet = spreadsheet.getSheetByName('CL');
  // シート上のFacebookアクセストークンと日付を取得
  ACCESS_TOKEN = cl_sheet.getRange("A1").getValue();

function kpifunctionCLTest(){

  var value_total_date = cl_sheet.getRange("A3:A356").getValues();
  Logger.log(value_total_date);

  // 昨日の日付取得
  var yesterday = new Date();
  yesterday.setDate(yesterday.getDate()-1);
  yesterday = Utilities.formatDate(new Date(yesterday), "JST", "yyyy-MM-dd");

  // 出力先の行を取得
  var target_row;
  var date;
  for(i = 1; i < 365; i++){
    date = Utilities.formatDate(new Date(value_total_date[i]), "JST", "yyyy-MM-dd");
    if(yesterday == date){
      target_row = i + 3;
      break;
  }
}

  // CL広告のレポートを取得し、シートに出力
  var cl_conversion = getReportByHttpRequest(yesterday, "date_start,date_stop,campaign_id,campaign_name,reach,spend,clicks,unique_clicks,ctr,cpm,actions,impressions", CL_CAMPAIGN_ID);
  if(cl_conversion.getResponseCode() != 200) {
    Logger.log("レポートを取得できませんでした");
  }
  var cl_report = getFacebookReport(cl_conversion);

  if(cl_conversion["data"] != ""){
    cl_sheet.getRange("B" + target_row).setValue(cl_report["data"][0]["date_stop"]);
    cl_sheet.getRange("C" + target_row).setValue(cl_report["data"][0]["clicks"]);
    cl_sheet.getRange("D" + target_row).setValue(cl_report["data"][0]["impressions"]);
    cl_sheet.getRange("E" + target_row).setValue(cl_report["data"][0]["spend"]);
    cl_sheet.getRange("F" + target_row).setValue(cl_report["data"][0]["cpm"]);
    cl_sheet.getRange("G" + target_row).setValue(cl_report["data"][0]["actions"][3]["value"]);
    cl_sheet.getRange("H" + target_row).setValue(cl_report["data"][0]["actions"][1]["value"]);
  } else {
    Logger.log("広告レポートの値がありません");
  }
}

 試したこと

tryとcatchを使おうとしましたがうまくいきませんでした。

 補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • k.tada

    2018/04/12 12:10

    コードはコードブロック(```〜```で囲う)で書いていただけますか。

    キャンセル

  • k.tada

    2018/04/12 12:12

    ダブルクオーテーション(")ではなく、バッククォート(`)でお願いします。

    キャンセル

  • Kazuki74

    2018/04/12 12:13

    初心者ですみません、対応いたしました。

    キャンセル

回答 2

checkベストアンサー

+4

GASで以前にこんな感じで書いてました。
このコードだとリトライして失敗ならあきらめますが、繰り返すように書き直せばいいかと思います。

function check_server(url){
  var code = check_server_retry(url);
  if(code != 200){
    Utilities.sleep(10000);
    return check_server_retry(url);
  } else {
    return code;
  }
}

function check_server_retry(url){
  try{
    var res = UrlFetchApp.fetch(url);
    return res.getResponseCode();
  } catch(e){
    return 999;
  }
}

元にしたコードはこちらです。
Google Apps Script でWEB死活監視(複数URL編) | Dozens Members' Blog

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+2

エラーがでている処理を再要求したらまたエラーになる可能性はないのでしょうか?
たとえばなんらかの障害によりエラーを返しているとして
そこに何度も要求がくるとなると、それは攻撃だとみなされると思います

 sample

雑ですがリトライ処理の考え方だけ

console.log("start");
var retry_count=1;
while(retry_count<10){
  try{
    dummy;//カウンタが5回まわるまでエラーになりつづける
    console.log("success");
    break;
  }catch(e){
    console.log(retry_count+":"+e);
    if(retry_count>=5) dummy=1;
  }
  retry_count++;
}
console.log("end");

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/04/12 12:21 編集

    20回実行したらだいたい1回エラーになります。
    連続してエラーになることは今のところ無いです。

    キャンセル

  • 2018/04/12 13:14

    同期処理ならwhleでリトライすればいいかもしれません
    tryで拾えないならエラーではなく結果のtrue/falseで返るかもしれません
    その場合はbooleanを元にthrowしてあげてください

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.97%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる