回答編集履歴

19

 

2023/01/05 13:14

投稿

退会済みユーザー
test CHANGED
@@ -39,8 +39,6 @@
39
39
  function postToGAS() {
40
40
  const postparam = {
41
41
  method: 'POST',
42
- accept: 'application/json',
43
- 'content-type': 'application/x-www-form-urlencoded',
44
42
  body: JSON.stringify(sourceList),
45
43
  };
46
44
 
@@ -122,7 +120,7 @@
122
120
 
123
121
  では、「mode: 'no-cors'」無しで通したい場合どうすればいいか?
124
122
  → そもそも`content-type': 'application/json' ` を指定するとプリフライト・リクエストになってしまうことが問題でした。
125
- したがって、リクエストがいわゆる単純リクエストになるように `content-type': 'application/x-www-form-urlencoded'` を指定します。
123
+ したがって、リクエストがいわゆる単純リクエストになるように `content-type': 'application/json'` を削除します。
126
124
 
127
125
 
128
126
  ### GASの修正

18

2022/12/23 15:54

投稿

退会済みユーザー
test CHANGED
@@ -66,13 +66,13 @@
66
66
 
67
67
  function doPost(e) {
68
68
  try {
69
- const res = doPostPloxy(e);
69
+ const res = doPostProxy(e);
70
70
  return res;
71
71
  } catch (err) {
72
72
  return ContentService.createTextOutput(JSON.stringify({ result: err.stack}));
73
73
  }
74
74
  }
75
- function doPostPloxy(e) {
75
+ function doPostProxy(e) {
76
76
  const reqParam = JSON.parse(e.postData.getDataAsString());
77
77
  const sheetNo = parseInt(reqParam.sheetNo) || 1;
78
78
  // シートの取得
@@ -164,7 +164,7 @@
164
164
  // Postリクエスト処理中のエラーをトラップするため try ~ catch で囲む。
165
165
  function doPost(e) {
166
166
  try {
167
- const res = doPostPloxy(e);
167
+ const res = doPostProxy(e);
168
168
  return res;
169
169
  } catch (err) {
170
170
  // エラーのスタックを JSON 形式で返す。
@@ -173,7 +173,7 @@
173
173
  }
174
174
 
175
175
  // doPost 処理を代理で行う
176
- function doPostPloxy(e) {
176
+ function doPostProxy(e) {
177
177
  // もともとの doPost の処理
178
178
  // ....
179
179
 

17

 

2022/12/21 15:35

投稿

退会済みユーザー
test CHANGED
@@ -149,14 +149,17 @@
149
149
 
150
150
 
151
151
  ##### ③ GASからの戻り値の設定
152
- クライアント側で fetch.thencatch 組んおられるようですが、
152
+ mode:'no-cors'設定していない場合単純リクエストの場合:
153
- GAS のWebアプリ
153
+ GAS のWebアプリからの戻り値
154
154
  + 正常終了の場合 → Access-Control-Allow-Origin * 付きでレスポンスが返ってくる
155
155
  + エラーが発生した場合 → Access-Control-Allow-Origin なしで返ってくる → CORS policy によりブロックされる
156
-
156
+ となります。
157
+
158
+ mode:'no-cors'を設定した場合:
157
- 修正前のコードだと、GAS側でエラーが発生して終了しても、クライアント側では CORS policy よりブロックされたということしかわかりません。(GAS 内部のエラー内容をクライアト側クリプトの catch ブロックで取ことはできません)
159
+ GAS のWebアプリからの戻り値は、正常終了かエラーにからず、opaque なレスポンスとな
158
-
160
+
159
- GAS 内部で発生したエラー内容を捕捉したいのであれば、GAS 側で doPost 内の処理を丸ごと try ~ catch ブロックで囲み、例外処理の中でエラー内容を(正常に)返すようなギミックを使います。(同時にエラー内容をログシートに出力するようにしてもよいでしょう)
161
+ したがって、GAS 内部で発生したエラー内容を捕捉したいのであれば、GAS 側で doPost 内の処理を丸ごと try ~ catch ブロックで囲み、例外処理の中でエラー内容を(正常に)返すようなギミックを使います。(同時にエラー内容をログシートに出力するようにしてもよいでしょう)
162
+
160
163
  ```js
161
164
  // Postリクエスト処理中のエラーをトラップするため try ~ catch で囲む。
162
165
  function doPost(e) {

16

 

2022/12/21 15:19

投稿

退会済みユーザー
test CHANGED
@@ -188,9 +188,9 @@
188
188
 
189
189
  ---
190
190
 
191
- 全く推奨しませんが、'content-type': 'application/json', かつ mode: 'no-cors' を指定した場合、
191
+ あまり推奨しませんが、'content-type': 'application/json', かつ mode: 'no-cors' を指定した場合、
192
192
  GAS 側に一切バグがなければ、一応スプレッドシートに正常に書き込まれます。
193
- ただし上述の通り、仮にその後コードを修正してエラーが発生した場合、エラー内容がわからないため、デバッグに苦労することになるでしょう。
193
+ ただし上述の通り、仮にその後GASのコードを修正してGAS内部でエラーが発生したとしてもクライアント側ではエラー内容がわからないため、try~catch で囲んでログシートにエラー内容を記録する / スクリプトをGCPと結びつけてGoogleコンソールでログを確認する等しない限り、デバッグに苦労することになるでしょう。
194
194
 
195
195
 
196
196
 

15

 

2022/12/21 13:39

投稿

退会済みユーザー
test CHANGED
@@ -51,7 +51,6 @@
51
51
  console.log(data.result);
52
52
  }).catch(err=>{
53
53
  console.log("Error!");
54
- console.log(err.status, err);
55
54
  });
56
55
  </script>
57
56
  </body>
@@ -187,6 +186,11 @@
187
186
  グローバル変数で定義している sheet という変数が doPost内で上書きされており、このために期待する動作になっていません。
188
187
  sheet はローカル変数とし、postJsonToSpreadSheet に引数として渡すようにすればよいでしょう。(修正後コード中の変数「targetSheet」参照)
189
188
 
189
+ ---
190
+
191
+ 全く推奨しませんが、'content-type': 'application/json', かつ mode: 'no-cors' を指定した場合、
192
+ GAS 側に一切バグがなければ、一応スプレッドシートに正常に書き込まれます。
193
+ ただし上述の通り、仮にその後コードを修正してエラーが発生した場合、エラー内容がわからないため、デバッグに苦労することになるでしょう。
190
194
 
191
195
 
192
196
 

14

 

2022/12/21 13:31

投稿

退会済みユーザー
test CHANGED
@@ -109,7 +109,7 @@
109
109
  ### CORS周りについて
110
110
 
111
111
  > ・fetchメソッドでPOSTする際に以下のエラーが出て、スプレッドシートに書き込みが出来ないようです。
112
- 元コードのように、`'content-type': 'application/json' `を指定すると、[プリフライト・リクエスト](https://developer.mozilla.org/ja/docs/Glossary/Preflight_request)になります。プリフライト・リクエストを処理するには、サーバーが OPTIONS リクエストに対応している必要がありますが、GAS は 対応していません
112
+ 元コードのように、`'content-type': 'application/json' `を指定すると、[プリフライト・リクエスト](https://developer.mozilla.org/ja/docs/Glossary/Preflight_request)になります。プリフライト・リクエストを処理するには、サーバーが対応している必要がありますが、GAS は 対応です
113
113
  このため (「mode: 'no-cors'」 がない状態で `'content-type': 'application/json' `を指定したリクエストを GAS に送った場合) GAS との通信は CORS policy によりブロックされます。
114
114
 
115
115
  > ・postparamに「mode: 'no-cors'」を追加したところ、「成功」が表示されましたが、スプレッドシートに書き込まれませんでした。
@@ -123,7 +123,7 @@
123
123
 
124
124
  では、「mode: 'no-cors'」無しで通したい場合どうすればいいか?
125
125
  → そもそも`content-type': 'application/json' ` を指定するとプリフライト・リクエストになってしまうことが問題でした。
126
- したがって、**単純リクエスト**になるように `content-type': 'application/x-www-form-urlencoded'` を指定します。
126
+ したがって、リクエストがいわゆる単純リクエストになるように `content-type': 'application/x-www-form-urlencoded'` を指定します。
127
127
 
128
128
 
129
129
  ### GASの修正

13

 

2022/12/21 13:21

投稿

退会済みユーザー
test CHANGED
@@ -1,12 +1,10 @@
1
1
 
2
- 「・投稿内容すべてをjavascriptで一括でPOSTして、GASでスプレッドシートに書き込みたい」について
2
+ 「・投稿内容すべてをjavascriptで一括でPOSTして、GASでスプレッドシートに書き込みたい」について、先に動作する回答例を示して、後半で解説します。
3
- 先に動作する回答例を示して、後半で解説します。(コメントやコードの大部分は、元質問のものを残しておりますのでご了承ください)
4
-
5
3
  (2番目の「・投稿内容すべてをスプレッドシートから一括でGETして、リストに表示したい」については具体的なコードが質問に一切示されておらず要件が全く不明であるため、割愛します)
6
4
 
7
5
  **<例>**
8
6
  **クライアント側HTML** sample.html
9
- (コメントやコードのは、元質問のものを残しております)
7
+ (コードの部は、元質問のものを残しております)
10
8
  ```html
11
9
  <!DOCTYPE html>
12
10
  <html lang="ja">

12

 

2022/12/21 13:19

投稿

退会済みユーザー
test CHANGED
@@ -6,6 +6,7 @@
6
6
 
7
7
  **<例>**
8
8
  **クライアント側HTML** sample.html
9
+ (コメントやコードの大部分は、元質問のものを残しております)
9
10
  ```html
10
11
  <!DOCTYPE html>
11
12
  <html lang="ja">
@@ -60,6 +61,7 @@
60
61
  ```
61
62
 
62
63
  **GAS側のスクリプト** code.gs
64
+ (コメントの大部分は、元質問のものを残しております)
63
65
  ```js
64
66
  const sheet_id = '*******************************';
65
67
  const sheet_name = 'シート1';

11

 

2022/12/21 13:00

投稿

退会済みユーザー
test CHANGED
@@ -139,12 +139,12 @@
139
139
  ```
140
140
 
141
141
 
142
- ##### ② sourceList に dataプロパティ がないに、GAS側でdataプロパティがあるもの受け取ろうとしている。
142
+ ##### ② クライアントから送るデータ(sourceListに dataプロパティ がないにもかかわらず、GAS側 data プロパティを読み取ろうとしている。
143
143
 
144
144
  ```js
145
145
  var data = JSON.parse(reqParam.data);
146
146
  ```
147
- この部分ですが、クライアントから送られてくる JSON には data プロパティがないにもかかわらず、dataを読み取ろうとする結果 reqParam.data は undefined になってしまいます。
147
+ この部分ですが、クライアントから送られてくる JSON には data プロパティがないにもかかわらず、data を読み取ろうとしており、結果 reqParam.data は undefined になってしまいます。
148
148
  → sourceList のデータに data プロパティを付けるか、sourceList はそのままにして「.data」を削除します。
149
149
  あと、①で parse 済みであれば、この部分のJSON.parse() も不要になります。
150
150
 

10

 

2022/12/21 12:58

投稿

退会済みユーザー
test CHANGED
@@ -170,8 +170,13 @@
170
170
  }
171
171
  }
172
172
 
173
+ // doPost 処理を代理で行う
173
174
  function doPostPloxy(e) {
174
175
  // もともとの doPost の処理
176
+ // ....
177
+
178
+ // 正常終了のメッセージを返す
179
+ return ContentService.createTextOutput(JSON.stringify({ result: "post done"}));
175
180
  }
176
181
  ```
177
182
 

9

 

2022/12/21 12:52

投稿

退会済みユーザー
test CHANGED
@@ -116,8 +116,8 @@
116
116
 
117
117
  「mode: 'no-cors'」に設定すると、たしかに CORS エラーは発生しませんが、レスポンスは [opaque](https://developer.mozilla.org/ja/docs/Web/API/Response/type#:~:text=opaque%3A%20%E3%82%AA%E3%83%AA%E3%82%B8%E3%83%B3%E9%96%93%E3%83%AA%E3%82%BD%E3%83%BC%E3%82%B9%E3%81%B8%E3%81%AE%20%22no%2Dcors%20%22%E3%83%AA%E3%82%AF%E3%82%A8%E3%82%B9%E3%83%88%E3%81%AB%E5%AF%BE%E3%81%99%E3%82%8B%E3%83%AC%E3%82%B9%E3%83%9D%E3%83%B3%E3%82%B9%E3%80%82%20%E5%8E%B3%E3%81%97%E3%81%8F%E5%88%B6%E9%99%90%E3%81%95%E3%82%8C%E3%81%A6%E3%81%84%E3%81%BE%E3%81%99%E3%80%82) となり、GAS から JSON を返しても無視されて、空っぽのデータが返ってきます。
118
118
 
119
- つまり GAS 内部でエラーがあろうとなかろうと、no-cors にしていると空っぽのレスポンスがポツンと返ってくるわけで(エラー扱いにならないので fetch の .catch にもつかまりません)、上のコードで「成功」と表示されたからと言ってGAS側が正常であるとは限りません。
119
+ つまり GAS 内部でエラーがあろうとなかろうと、no-cors にしていると常に空っぽのレスポンスがポツンと返ってくるわけで(エラー扱いにならないので fetch の .catch にもつかまりません)、上のコードで「成功」と表示されたからと言ってGAS側の処理が正常に完了したとは限りません。
120
- (実際、元コードは GAS 側のコードにいくつかエラーがあり、スプレッドシートへ正常書き込みが行われる前に終了しています。)
120
+ (実際、元コードは GAS 側のコードにいくつかエラーがあり、スプレッドシートへ正常書き込みが行われる前にエラーで終了しています。)
121
121
 
122
122
  結論として、GAS から post後の正常メッセージ/エラーメッセージを、内容がわかる形で返そうとするならば「mode: 'no-cors'」は使えません。
123
123
 

8

 

2022/12/21 12:50

投稿

退会済みユーザー
test CHANGED
@@ -117,6 +117,7 @@
117
117
  「mode: 'no-cors'」に設定すると、たしかに CORS エラーは発生しませんが、レスポンスは [opaque](https://developer.mozilla.org/ja/docs/Web/API/Response/type#:~:text=opaque%3A%20%E3%82%AA%E3%83%AA%E3%82%B8%E3%83%B3%E9%96%93%E3%83%AA%E3%82%BD%E3%83%BC%E3%82%B9%E3%81%B8%E3%81%AE%20%22no%2Dcors%20%22%E3%83%AA%E3%82%AF%E3%82%A8%E3%82%B9%E3%83%88%E3%81%AB%E5%AF%BE%E3%81%99%E3%82%8B%E3%83%AC%E3%82%B9%E3%83%9D%E3%83%B3%E3%82%B9%E3%80%82%20%E5%8E%B3%E3%81%97%E3%81%8F%E5%88%B6%E9%99%90%E3%81%95%E3%82%8C%E3%81%A6%E3%81%84%E3%81%BE%E3%81%99%E3%80%82) となり、GAS から JSON を返しても無視されて、空っぽのデータが返ってきます。
118
118
 
119
119
  つまり GAS 内部でエラーがあろうとなかろうと、no-cors にしていると空っぽのレスポンスがポツンと返ってくるわけで(エラー扱いにならないので fetch の .catch にもつかまりません)、上のコードで「成功」と表示されたからと言ってGAS側が正常であるとは限りません。
120
+ (実際、元コードは GAS 側のコードにいくつかエラーがあり、スプレッドシートへ正常書き込みが行われる前に終了しています。)
120
121
 
121
122
  結論として、GAS から post後の正常メッセージ/エラーメッセージを、内容がわかる形で返そうとするならば「mode: 'no-cors'」は使えません。
122
123
 

7

 

2022/12/21 12:47

投稿

退会済みユーザー
test CHANGED
@@ -109,12 +109,12 @@
109
109
  ### CORS周りについて
110
110
 
111
111
  > ・fetchメソッドでPOSTする際に以下のエラーが出て、スプレッドシートに書き込みが出来ないようです。
112
- 元コードのように、`content-type': 'application/json' `を指定すると、プリフライト・リクエストになるため、OPTIONS に対応していない GAS からの通信CORS policy によりブロックされ
112
+ 元コードのように、`'content-type': 'application/json' `を指定すると、[プリフライト・リクエスト](https://developer.mozilla.org/ja/docs/Glossary/Preflight_request)になります。プリフライト・リクエストを処理すにはサーバーが OPTIONS リクエストに対応している必要がありますが、GAS は 対応していせん
113
+ このため (「mode: 'no-cors'」 がない状態で `'content-type': 'application/json' `を指定したリクエストを GAS に送った場合) GAS との通信は CORS policy によりブロックされます。
113
114
 
114
115
  > ・postparamに「mode: 'no-cors'」を追加したところ、「成功」が表示されましたが、スプレッドシートに書き込まれませんでした。
115
116
 
116
- 「mode: 'no-cors'」に設定すると、レスポンスは [opaque(透明の意味)](https://developer.mozilla.org/ja/docs/Web/API/Response/type#:~:text=opaque%3A%20%E3%82%AA%E3%83%AA%E3%82%B8%E3%83%B3%E9%96%93%E3%83%AA%E3%82%BD%E3%83%BC%E3%82%B9%E3%81%B8%E3%81%AE%20%22no%2Dcors%20%22%E3%83%AA%E3%82%AF%E3%82%A8%E3%82%B9%E3%83%88%E3%81%AB%E5%AF%BE%E3%81%99%E3%82%8B%E3%83%AC%E3%82%B9%E3%83%9D%E3%83%B3%E3%82%B9%E3%80%82%20%E5%8E%B3%E3%81%97%E3%81%8F%E5%88%B6%E9%99%90%E3%81%95%E3%82%8C%E3%81%A6%E3%81%84%E3%81%BE%E3%81%99%E3%80%82)
117
- となり、GAS から JSON を返しても無視されて、空っぽのデータが返ってきます。
117
+ 「mode: 'no-cors'」に設定すると、たしかに CORS エラーは発生しませんが、レスポンスは [opaque](https://developer.mozilla.org/ja/docs/Web/API/Response/type#:~:text=opaque%3A%20%E3%82%AA%E3%83%AA%E3%82%B8%E3%83%B3%E9%96%93%E3%83%AA%E3%82%BD%E3%83%BC%E3%82%B9%E3%81%B8%E3%81%AE%20%22no%2Dcors%20%22%E3%83%AA%E3%82%AF%E3%82%A8%E3%82%B9%E3%83%88%E3%81%AB%E5%AF%BE%E3%81%99%E3%82%8B%E3%83%AC%E3%82%B9%E3%83%9D%E3%83%B3%E3%82%B9%E3%80%82%20%E5%8E%B3%E3%81%97%E3%81%8F%E5%88%B6%E9%99%90%E3%81%95%E3%82%8C%E3%81%A6%E3%81%84%E3%81%BE%E3%81%99%E3%80%82) となり、GAS から JSON を返しても無視されて、空っぽのデータが返ってきます。
118
118
 
119
119
  つまり GAS 内部でエラーがあろうとなかろうと、no-cors にしていると空っぽのレスポンスがポツンと返ってくるわけで(エラー扱いにならないので fetch の .catch にもつかまりません)、上のコードで「成功」と表示されたからと言ってGAS側が正常であるとは限りません。
120
120
 

6

 

2022/12/21 12:40

投稿

退会済みユーザー
test CHANGED
@@ -70,9 +70,7 @@
70
70
  const res = doPostPloxy(e);
71
71
  return res;
72
72
  } catch (err) {
73
- SpreadsheetApp.openById(sheet_id).getSheetByName("log").appendRow([err.stack]);
74
- return ContentService.createTextOutput(JSON.stringify({ result:err.stack}));
73
+ return ContentService.createTextOutput(JSON.stringify({ result: err.stack}));
75
-
76
74
  }
77
75
  }
78
76
  function doPostPloxy(e) {

5

 

2022/12/21 12:38

投稿

退会済みユーザー
test CHANGED
@@ -1,5 +1,9 @@
1
1
 
2
+ 「・投稿内容すべてをjavascriptで一括でPOSTして、GASでスプレッドシートに書き込みたい」について
2
3
  先に動作する回答例を示して、後半で解説します。(コメントやコードの大部分は、元質問のものを残しておりますのでご了承ください)
4
+
5
+ (2番目の「・投稿内容すべてをスプレッドシートから一括でGETして、リストに表示したい」については具体的なコードが質問に一切示されておらず要件が全く不明であるため、割愛します)
6
+
3
7
  **<例>**
4
8
  **クライアント側HTML** sample.html
5
9
  ```html

4

 

2022/12/21 12:32

投稿

退会済みユーザー
test CHANGED
@@ -172,10 +172,10 @@
172
172
  }
173
173
  ```
174
174
 
175
- ##### ④ あるべき変数がない。
175
+ ##### ④ 未定義の変数
176
176
  ss という変数が内部で使われていますがどこにも定義されていません。おそらくスプレッドシートのことだろうと推測したので、とりあえずスプレッドシートオブジェクトを格納したグローバル変数として定義しています。
177
177
 
178
- ##### ⑤ sheet 変数の上書き
178
+ ##### ⑤ グローバル変数の(意図しない?)上書き
179
179
  グローバル変数で定義している sheet という変数が doPost内で上書きされており、このために期待する動作になっていません。
180
180
  sheet はローカル変数とし、postJsonToSpreadSheet に引数として渡すようにすればよいでしょう。(修正後コード中の変数「targetSheet」参照)
181
181
 

3

 

2022/12/21 12:29

投稿

退会済みユーザー
test CHANGED
@@ -173,11 +173,11 @@
173
173
  ```
174
174
 
175
175
  ##### ④ あるべき変数がない。
176
- ss という変数が内部で使われていますがどこにも定義されていません。おそらくスプレッドシートを使いたかったためと推測したので、グローバル領域にスプレッドシート変数として定義しています。
176
+ ss という変数が内部で使われていますがどこにも定義されていません。おそらくスプレッドシートのこだろうと推測したので、とりあえずスプレッドシートオブジェクトを格納したグローバル変数として定義しています。
177
177
 
178
178
  ##### ⑤ sheet 変数の上書き
179
- グローバル変数で定義している sheet という変数が doPost内で上書きされていますが、このために期待する動作になっていません。
179
+ グローバル変数で定義している sheet という変数が doPost内で上書きされており、このために期待する動作になっていません。
180
- sheet はローカル変数とし、postJsonToSpreadSheet に引数として渡すようにすればよいでしょう。
180
+ sheet はローカル変数とし、postJsonToSpreadSheet に引数として渡すようにすればよいでしょう。(修正後コード中の変数「targetSheet」参照)
181
181
 
182
182
 
183
183
 

2

 

2022/12/21 12:27

投稿

退会済みユーザー
test CHANGED
@@ -152,9 +152,9 @@
152
152
  + 正常終了の場合 → Access-Control-Allow-Origin * 付きでレスポンスが返ってくる
153
153
  + エラーが発生した場合 → Access-Control-Allow-Origin なしで返ってくる → CORS policy によりブロックされる
154
154
 
155
- エラーの場合、CORS policy によりブロックされめ、レスポンス内容を クライアント側スクリプトの catch ブロックで取り出すことはできません
155
+ 修正前のコードだと、GAS側でエラーが発生して終了してもクライアント側では CORS policy によりブロックされたということしかわかりません。(GAS 部のエラー内容をクライアント側スクリプトの catch ブロックで取り出すことはできません
156
156
 
157
- したがってエラー内容を捕捉したいのであれば、GAS 側で doPost 内の処理を丸ごと try ~ catch ブロックで囲み、例外処理の中でエラー内容を(正常に)返すようなギミックを使います。(同時にエラー内容をログシートに出力するようにしてもよいでしょう)
157
+ GAS 内部で発生したエラー内容を捕捉したいのであれば、GAS 側で doPost 内の処理を丸ごと try ~ catch ブロックで囲み、例外処理の中でエラー内容を(正常に)返すようなギミックを使います。(同時にエラー内容をログシートに出力するようにしてもよいでしょう)
158
158
  ```js
159
159
  // Postリクエスト処理中のエラーをトラップするため try ~ catch で囲む。
160
160
  function doPost(e) {

1

 

2022/12/21 12:22

投稿

退会済みユーザー
test CHANGED
@@ -154,7 +154,7 @@
154
154
 
155
155
  エラーの場合、CORS policy によりブロックされるため、レスポンス内容を クライアント側スクリプトの catch ブロックで取り出すことはできません。
156
156
 
157
- したがってエラー内容を捕捉したいのであれば、GAS 側で try ~ catch ブロックで囲んで、例外処理の中でエラー内容を返すようなギミックを使います。(同時にエラー内容をログシートに出力するようにしてもよいでしょう)
157
+ したがってエラー内容を捕捉したいのであれば、GAS 側で doPost 内の処理を丸ごと try ~ catch ブロックで囲、例外処理の中でエラー内容を(正常に)返すようなギミックを使います。(同時にエラー内容をログシートに出力するようにしてもよいでしょう)
158
158
  ```js
159
159
  // Postリクエスト処理中のエラーをトラップするため try ~ catch で囲む。
160
160
  function doPost(e) {