1行目にカラム名を入れてある SpreadSheet で1行目以下を使った GAS を書いていてうまく動作してなかったメモ。
エラー箇所を探す
Slack連携で使っているスクリプトだったので、各関数をまずは単独で動くモックのスクリプトに変換しました。
次に怪しい箇所に try - catch
を仕込んでいきます。
const mockGetAllData = () => { try { const sheet = getSheet(); if (!sheet) { return []; } // range: Object const range = sheet.getRange(2, 1, sheet.getLastRow() - 1, COL_NUM); // to Array const data = range.getValues(); Logger.log(`SUCCESS ${data.length}`); } catch (err) { Logger.log(err); } }
2行目からデータのある最後の行までをのセルのデータを全て取得して配列で返す関数
ここで sheet が空の時 Exception: 範囲の行数には 1 以上を指定してください。 というエラーが発生していました。
getRange で 0行の range を取得しようとしていたのが問題だった。
getRange(row, column, numRows, numColumns)
const range = sheet.getRange(2, 1, sheet.getLastRow() - 1, COL_NUM);
この range を取得している部分で、sheet にデータがない状態の場合 sheet.getLastRow()
は 1
(カラム名を入れている1行目のみ) なので、numRows
が 0
つまり、範囲を作成することができないのでエラーが発生していた。ということでした。
getLastRow()
で動的に範囲を作成する場合、データがなく範囲が作成できない例外を考慮しておく必要がある
const mockGetAllData = () => { try { const sheet = getSheet(); if (!sheet) { return []; } const numRows = sheet.getLastRow() - 1; if (numRows < 1) { return []; } // range: Object const range = sheet.getRange(2, 1, numRows, COL_NUM); // to Array const data = range.getValues(); Logger.log(`SUCCESS ${data.length}`); } catch (err) { Logger.log(err); } }
範囲が作成できない場合は空配列を返すようにすればOK
これで問題なく動作するようになりました。
所感
Slack 連携させているスクリプトで、Apps Script ダッシュボード を見てもエラー発生の行数も不明で、エラーが起きたという事実以外読み取ることができず当初判らず原因を突き止めるのに苦労しました。
怪しそうな部分に try - catch
を仕込みまくると、Apps Script ダッシュボード でも catch されたエラーの文言が表示されるようになるので、そこから問題箇所を突き止め、モック関数を作成してスクリプト内で関数を実行して修正するという手順を踏みました。
関数の責任範囲を小さくしておいたおかげでモック化が楽だったので、関数は小さくしておくのが正義だなーと感じました。
それよか、Apps Script ダッシュボード エラー発生時にせめてエラーが発生した行数やエラーメッセージ表示してくれませんかね…
エラー発生で絞り込めるのにダッシュボードの意味とは… って感じで…
とりあえず、うまく動作してなかったら try - catch
仕込みまくるという手作業の温かみのあるデバックが有効…。学んだ。
[参考]
スプレッド (Spread) とは、パンやクラッカーなどに塗る「塗り物」のこと。 英語の動詞としての「広げる」、または「薄く延ばす」という意味に由来する。
なるほどな。₍ ᐢ. ̫ .ᐢ ₎