Can I get the error code from Twilio server response? - google-apps-script

I'm using the instructions provided by Twilio to send SMS messages from a Google Sheet. I'm using the UrlFetchApp.fetch(url,params) to make the post request. Currently it's catching any errors and logging it to a cell.
for (i in data) {
var row = data[i];
try {
response_data = sendSms(row[0], row[1]);
status = "Sent";
} catch(err) {
status = "Error";
}
sheet.getRange(startRow + Number(i), 4).setValue(status);
}
The err is quite long Exception: Request failed for https://api.twilio.com/2010-04-01/Accounts/twilio SID/Messages.json returned code 400. Truncated server response: {"code": 21211, "message": "The 'To' number ##### is not a valid phone number.", "more_info": "https://www.twilio.com/docs/errors/21211", "stat... (use muteHttpExceptions option to examine full response).
Is it possible to get just the code value? In the example above, that would be 21211. I'd like to show the user, but in more user friendly language.
I have tried to use the getContentText() as documented but couldn't get it to return anything.

Related

HTTP Request to Discord API Through Google Apps Script Results in 403 Error With Response "Error Code 1020"

I'm having trouble getting guild channels with this code in Google Apps Script.
var token = "MY_TOKEN"
var url = "https://discord.com/api/v10/guilds/[GUILD_ID]/channels"
var header = {
Authorization: "Bot " + token
}
function myFunction(){
var params = {
method: "get",
headers: header,
muteHttpExceptions: false
}
var response = UrlFetchApp.fetch(url,params)
Logger.log(response.getContentText())
}
Running myFunction() results in this error message:
Exception: Request failed for https://discord.com returned code 403. Truncated server response: error code: 1020 (use muteHttpExceptions option to examine full response)
or just this if the muteHttpExceptions value is true:
error code: 1020
Some information that may be useful to diagnose my problem:
My bot is in my server, but it's shown to be offline in the member list (does it matter?)
My bot is a private bot
I have made sure that the bot token and guild ID are correct
I invited the bot to my server via a generated link in OAuth2 URL generator in Discord Developer Portal. I checked the bot scope only with administrator permission. (Additional info: The first time I tried generating URL, it didn't need a redirect URL. But for some reason, it requires me to select one from a dropdown list now, but when I click on the dropdown, the list is empty as shown in the screenshot, so I can't select one and can't generate URL from there anymore.)
Get Current User Guild (/users/#me/guilds) runs perfectly fine. It returns this array:
[
{
"id": "[GUILD_ID]",
"name": "[GUILD_NAME]",
"icon": null,
"owner": false,
"permissions": "4398046511103",
"features": [
"APPLICATION_COMMAND_PERMISSIONS_V2"
]
}
]
I think my problem has something to do with the bot permissions, but I'm just lost.

getResponseCode() method doesn't return expected response code

I have 2 questions about Google App Script Services getResponseCode() method.
1) "Unexpected Error"
When I run the getResponseCode() method, I got "Unexpected Error...".
https://developers.google.com/apps-script/reference/url-fetch/http-response#getResponseCode()
var response = UrlFetchApp.fetch(url, {muteHttpExceptions: true});
responseCode = response.getResponseCode();
Unexpected error: https://www.example.com/
※I can't tell the url for business reasons.
HTTP response status codes don't include "Unexpected Error".
https://developer.mozilla.org/en-US/docs/Web/HTTP/Status
Please tell me what response codes actually return, when this error occurs?
2) getResponseCode() method didn't work as expected
When I run the code below, I got "200".
I expected "301" in response to the "http://google.com/" request.
function myFunction() {
var response = UrlFetchApp.fetch("http://google.com/");
 Logger.log(response.getResponseCode());
}
I think getResponseCode() method doesn't return actual http status codes.
Please tell me why I got "200" instead of "301".
get 301 response in browser
get 200 response instead of 301
This happens because the request is following the redirect. Take a look at the available parameters in the UrlFetchApp.fetch() method. You'll see followRedirects, which defaults to true.
Make this small change and you'll get the expected 301.
function myFunction() {
var response = UrlFetchApp.fetch("http://google.com/", { followRedirects: false });
 Logger.log(response.getResponseCode());
}

fileAttachment.Load() not working for second attachment

I am getting
"The specified object was not found in the store., The process failed to
get the correct properties."
error while loading the FileAttachment.
Here is my code
foreach (Attachment attachment in message.Attachments)
{
if (attachment is FileAttachment)
{
if ( attachment.IsInline==true)
{
// in line image , may be part of signature image not considering for process
continue;
}
else
{
FileAttachment fileAttachment = attachment as FileAttachment;
string route1 = ConfigurationManager.AppSettings["route"];
string route = route1 + fileAttachment.Name;
String strFileUploadResut = "false";
try
{
fileAttachment.Load(route1 + fileAttachment.Name);
FilenetFactory FileNetUploadUtil = new FilenetFactory();
Console.WriteLine(" Sending File " + fileAttachment.Name + " to OneScan webservice.");
}
catch (Exception E)
{
log.logText("Exception during sending to webservice. "+ E.Message, "Info");
if (E.Message.ToString() == "The specified object was not found in the store., The process failed to get the correct properties.")
{ }
For First attachment its load properly. for second attachment i am getting this error. Not sure why its work first time and throws exception second time. What wrong i am doing here? any advice !!
Sounds like it might be another process working on the same message, eg if another process has moved the message between your calls to the server then Id's you have will be invalid and that would be the error you would expect to receive from the server. A way to test that would be to try to load the message after you receive that error.

Xamarin Social component fails to retrieve Twitter json stream

I'm using the following to read Twitter json. It works with one uri and not another. The uri's work with the Twitter API console but not Xamarin.Social. I have read and write permissions on the Twitter app so I can't see where I'm going wrong.
https://api.twitter.com/1.1/account/settings.json <-- works
https://api.twitter.com/1.1/users/show.json?screen_name=AUserName <-- fails (see error below)
request.GetResponseAsync ().ContinueWith (response => {
if (response.IsFaulted)
{
Console.WriteLine (response.Exception.Flatten ());
}
var json = response.Result.GetResponseText ();
System.AggregateException: One or more errors occured ---> System.Net.WebException: The remote server returned an error: (401) Unauthorized.
at System.Net.HttpWebRequest.CheckFinalStatus (System.Net.WebAsyncResult result) [0x0030c] in /Developer/MonoTouch/Source/mono/mcs/class/System/System.Net/HttpWebRequest.cs:1606
at System.Net.HttpWebRequest.SetResponseData (System.Net.WebConnectionData data) [0x00141] in /Developer/MonoTouch/Source/mono/mcs/class/System/System.Net/HttpWebRequest.cs:1423
--- End of inner exception stack trace ---
--> (Inner exception 0) System.Net.WebException: The remote server returned an error: (401) Unauthorized.
at System.Net.HttpWebRequest.CheckFinalStatus (System.Net.WebAsyncResult result) [0x0030c] in /Developer/MonoTouch/Source/mono/mcs/class/System/System.Net/HttpWebRequest.cs:1606
at System.Net.HttpWebRequest.SetResponseData (System.Net.WebConnectionData data) [0x00141] in /Developer/MonoTouch/Source/mono/mcs/class/System/System.Net/HttpWebRequest.cs:1423
[quick google search gave this but not sure if its relevant: https://dev.twitter.com/discussions/15206]
// UPDATE ***********
Does this extra infor help or you need more details? If so then what details are required?
public Account Account
{
get
{
var task = Service.GetAccountsAsync ()
.ContinueWith (accounts =>
{
return accounts.Result.ToList ().FirstOrDefault ();
});
return task.Result;
}
set
{
AccountStore.Create ().Save (value, SocialPlatform.ToString ());
}
}
// later on
// when endpoint = "https://api.twitter.com/1.1/account/settings.json" <-- works, json returned
// when endpoint = "https://api.twitter.com/1.1/users/show.json?screen_name=XXXX" <-- IsFaulted with above error,
var request = Service.CreateRequest ("GET", endpoint, Account);
request.GetResponseAsync ().ContinueWith (response => {
if (response.IsFaulted)
{
Console.WriteLine (response.Exception.Flatten ());
return;
}
var json = response.Result.GetResponseText ();
Console.WriteLine (json);
});
It seems like you are not authorised when you make this call.
From Xamarin.Social documentation.
Xamarin.Social uses the Xamarin.Auth library to fetch and store
Account objects.
Each service exposes a GetAuthenticateUI method that returns a
Xamarin.Auth.Authenticator object that you can use to authenticate the
user. Doing so will automatically store the authenticated account so
that it can be used later.
The reason why it works in Twitter API console is that you have authorised there prior to making a call.
If you are already authorising in your app then please post the code you use to authorise.

How to catch UrlFetchApp.fetch exception

Is there any way to catch the exception from UrlFetchApp.fetch?
I thought I can use response.getResponseCode() to check the response code, but I'm not able to, for e.g when there is 404 error, the script not continue and just stop at UrlFetchApp.fetch
Edit: This parameter is now documented here.
You can use the undocumented advanced option "muteHttpExceptions" to disable exceptions when a non-200 status code is returned, and then inspect the status code of the response. More information and an example is available on this issue.
The trick is passing the muteHttpExceptions param of UrlFetchApp.fetch().
Here an example (untested):
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))
// ...
}
For some reason if the URL is not available (e.g. the service you're trying to use is down) it still looks like is throwing an error so you may still need to use a try/catch block.
why don't you use try catch and handle the error in catch block
try{
//Your original code, UrlFetch etc
}
catch(e){
// Logger.log(e);
//Handle error e here
// Parse e to get the response code
}
You can manually parse the caught error, but it's not recommended. When catching the exception (that is being thrown in case muteHttpExceptions is turned off), the error object would be in the following format:
{
"message": "Request failed for ___ returned code___. Truncated server response: {___SERVER_RESPONSE_OBJECT___} (use muteHttpExceptions option to examine full response)",
"name": "Exception",
"fileName": "___FILE_NAME___",
"lineNumber": ___LINE_NUMBER___,
"stack": "___STACK_DETAILS___"
}
If you for some reason prefer not using muteHttpExceptions, you could catch the exception e, look at e.message, substring the text between "Truncated server response: " and " (use muteHttpExceptions option to examine full response)", JSON.parse() it, and the returned object would be the error returned from the api call.
I wouldn't suggest it over muteHttpExceptions, just wanted to show the best way to get the error object this way.
Anyways, try-catch your UrlFetchApp.fetch() call to make sure you catch the unhandled exceptions, like 404.