UrlFetchApp を使って、Http 通信を行うスクリプトを作っていたのですが、
Http Response 200 以外のコード が返る場合は、
例外がスローされており、どうハンドリングするべきか調べた結果を記載します。
Google App Script の Version
Version 情報なんてあるのかとは思いましたが、
Relese Notes はあり、そこで機能の追加/削除情報はウォッチングできます。1
Release Notes | Apps Script | Google Developers
[1] Deprecated されるAPI のあるので、会社で使用している場合等は定期的に見た方がよいと感じました。
参考
-
google apps script - How to catch UrlFetchApp.fetch exception - Stack Overflow
UrlFetchApp の exception のハンドリング方法について -
Handle Errors in Apps Script with Try and Catch | Drive Bunny
exception 自体の扱いについて -
Google Apps ScriptのUrlFetchAppでSSL証明書のエラーを回避する | ハックノート
自己証明書エラーの回避方法 -
Google Apps Script: エラー情報の取得 | kenlog
エラーオブジェクトのプロパティの取得
muteHttpExceptions
に true
を設定する
デフォルトだとエラーを吐きますが、muteHttpExceptions
のオプション設定で、
エラーを吐かずにHttpResponse を返してくれるようになります。
StackOverFlow のコードのコピペになりますが、以下のように記述できます。
var payload = {"value": "key"};
var response = UrlFetchApp.fetch(
url,
{
method: "PUT",
contentType: "application/json",
payload: JSON.stringify(payload),
muteHttpExceptions: true,
}
);
var responseCode = response.getResponseCode();
var responseBody = response.getContentText();
if (responseCode === 200) {
var responseJson = JSON.parse(responseBody);
// ...
} else {
Logger.log(Utilities.formatString("Request failed. Expected 200, got %d: %s", responseCode, responseBody));
// ...
}
try~catch
する
現在作成しているスクリプトではこちらの実装としました。
var errors = new Array();
for each (var sitemapUrl in sitemapUrls) {
for each (var target in pingTargets) {
try {
var requestUrl = target + "?sitemap=";
var requestUrl = requestUrl + encodeURIComponent(sitemapUrl);
info("URL:>>>" + sitemapUrl + "|Target:>>>" + target);
// GETリクエスト
var response = UrlFetchApp.fetch(requestUrl);
info("ResponseCode:>>" + response.getResponseCode());
} catch (ex) {
errors.push("Message: " + ex.message + "\r\nFile: " + ex.fileName + "\r\nLine: " + ex.lineNumber + "\r\n");
}
}
}
if(errors.length > 0) {
var recipients = getColumValues("config", "C", 1);
sendEmails(recipients, "Ping sitemap error report", errors.join("\r\n"));
}
例外をcatch 後は、ex.fileName
とか、ex.lineNumber
等で、例外が発生した情報が取得できます。
ex.message
を出力しておけば大概のことはわかりそうです。
muteHttpExceptions
に true
を設定してもExceptionは発生する
muteHttpExceptions
に true
を設定していてもexceptionが発生するケースがあります。
google apps script - UrlFetchApp muteHttpException doesnt work - Stack Overflow
にも記載されていますが、URLが不正であったり、DNS エラーが発生すると、exception がスローされます。
実際にexception でスケジュール実行中のスクリプトがエラーを吐いて落ちていました。
テストスクリプトを作成して、exception 発生時のメッセージを記録してみました。
テストスクリプトでは、
Google Apps ScriptのUrlFetchAppでSSL証明書のエラーを回避する | ハックノート
を参考に"validateHttpsCertificates" : false
を設定して、自己証明書の場合のエラーを回避しています。
DNSエラー
- 実装
function testUrlFetchAppDNSError() { var url = "https://localhost.unknown"; var options = { "muteHttpExceptions" : true, "validateHttpsCertificates" : false, "followRedirects" : false, } try { var response = UrlFetchApp.fetch(url, options); Logger.info(url + ":responscode>>>" + response.getResponseCode()); } catch(e) { Logger.log("message:" + e.message + "\nfileName:" + e.fileName + "\nlineNumber:" + e.lineNumber + "\nstack:" + e.stack); } }
- 実装
[17-09-01 22:08:07:237 JST] message:DNS エラー: https://localhost.unknown
fileName:コード
lineNumber:22
stack: at コード:22 (testUrlFetchAppDNSError)
不正なURL
-
実装
function testInvalidURL() { var url = "https://^/localhost.com"; var options = { "muteHttpExceptions" : true, "validateHttpsCertificates" : false, "followRedirects" : false, } try { var response = UrlFetchApp.fetch(url, options); Logger.info(url + ":responscode>>>" + response.getResponseCode()); } catch(e) { Logger.log("message:" + e.message + "\nfileName:" + e.fileName + "\nlineNumber:" + e.lineNumber + "\nstack:" + e.stack); } }
-
エラーログ
[17-09-01 22:31:39:835 JST] message:無効な引数: https://^/localhost.com fileName:コード lineNumber:22 stack: at コード:22 (testInvalidURL)
使用できないアドレス
これは、実際スクリプトをスケジューラ実行している際に発生していました。
アクセスしているURL からの応答がなくしばらく待ったあとに、エラーが発生しています。
推測ではありますが、アクセス拒否されている場合に発生しているように思われます。
-
実装
function testUrlFetchAppUnsedAddress() { var url = "https://localhost.com"; var options = { "muteHttpExceptions" : true, "validateHttpsCertificates" : false, "followRedirects" : false, } try { var response = UrlFetchApp.fetch(url, options); Logger.info(url + ":responscode>>>" + response.getResponseCode()); } catch(e) { Logger.log("message:" + e.message + "\nfileName:" + e.fileName + "\nlineNumber:" + e.lineNumber + "\nstack:" + e.stack); } }
-
エラーログ
[17-09-01 22:06:19:125 JST] message:使用できないアドレス: https://localhost.com fileName:コード lineNumber:22 stack: at コード:22 (testUrlFetchAppDNSError)
Exception が発生しても処理を続行させたいケース等は、"muteHttpExceptions" : true
だけでなく、try~catch
もしたほうがいいようです。
以上です。
コメント