When debugging external host communication with UrlFetchApp
, there are a few tools available to you.
It helps to muteHttpExceptions
so you can view them. (In fact, you can simply write your code to handle them yourself, and only throw
for exceptions you really don't expect.)
This is done by adding 'muteHttpExceptions' : true
to your fetch
parameters.
With exceptions muted, fetch
won't throw an exception, instead it will pass failure response codes in the HTTPResponse. From there, you can extract the response code and content text for debugging (or automatic handling).
Modify your code like this, to log errors:
var response = UrlFetchApp.fetch(url, options);
var rc = response.getResponseCode();
if (rc !== 200) {
// HTTP Error
Logger.log("Response (%s) %s",
rc,
response.getContentText() );
// Could throw an exception yourself, if appropriate
}
Run, and here's what we see:
[15-08-27 11:18:06:688 EDT] Response (404.0) {
"error": true,
"message": "Could not find API"
}
Some APIs give very rich error messages. This one, not so much. But it does tell us that we have the URL correct, but that the service couldn't find the API we want. Next, dig into why that is so.
We can examine the fetch
options and parameters by using getRequest()
. Add this line just above the existing fetch()
call, and put a breakpoint on the fetch()
.
var test = UrlFetchApp.getRequest(url, options);
Start the function in the debugger, and when the breakpoint is hit, examine the contents of test
carefully.
A common problem is with the encoding of the POST
payload. You hand-encoded #
to %23
and used JSON.stringify()
, so no problem there.
Checking the remaining options, we see that the contentType
isn't 'application/json'
.

So now you look at your code and find that the name for contentType
was mis-typed as content-Type
. Remove the hyphen, and try again.
Keep going until you've identified and fixed any other bugs.
Another tip is to use encodeURIComponent()
to escape restricted characters in your fetch
parameters, rather than hand-encoding them. It simplifies your code, because you can write the "real" characters like #
instead of their UTF-8 escape sequences like %23
.
Updated code:
function PostParameters2() {
var parameters = {
apikey: "--apikey--",
urls: [
encodeURIComponent("https://twitter.com/search?q=#running"),
encodeURIComponent("https://twitter.com/search?q=#swimming")
]
};
var data = JSON.stringify(parameters);
var url = 'https://kimonolabs.com/kimonoapis/--apiId--/update';
var options = {
'method': 'POST',
'contentType': 'application/json',
'payload': data,
'muteHttpExceptions' : true
};
var test = UrlFetchApp.getRequest(url, options);
var response = UrlFetchApp.fetch(url, options);
var rc = response.getResponseCode();
if (rc !== 200) {
// HTTP Error
Logger.log("Response (%s) %s",
rc,
response.getContentText() );
// Could throw an exception yourself, if appropriate
}
else {
// Successful POST, handle response normally
var responseText = response.getContentText();
Logger.log(responseText);
}
}