How to properly handle Google SDK errors in Google App Script - debugging

I am writing a google web app which uses the Admin Directory a lot. However I was wondering how the error handling should be done since I do not get a proper error object back when a request to the api fails.
Example: I want to check if a custom schema exists and if not I want to do something else:
try{
var resp = AdminDirectory.Schemas.get("129898rgv", "someCustomSchema");
}catch(err){
// if schema does not exist do this
schemaNotExistFunction();
Logger.log(err);
}
Unfortunately I do not even get the http status code back from the err. Is there another way to handle errors in Google Apps Script?

Instead of
Logger.log(error)
use
Logger.log('%s, %s',error.message, error.stack);
See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error for a complete list of Error instance properties
The above because Logger.log parses the parameter as string. When you pass an error object error.name is logged, by the other hand by using
Example
Running the following code in an standalone project using the new runtime (V8) will log a couple of messages.
function myFunction() {
try{
SpreadsheetApp.getUi();
} catch (error) {
Logger.log(error);
Logger.log('%s, %s', error.message, error.stack);
}
}
Another alternative is to use console.log instead of Logger.log
function myFunction() {
try{
SpreadsheetApp.getUi();
} catch (error) {
console.log(error);
console.log('%s, %s', error.message, error.stack);
}
}

Related

Make JDA Discord Bot send a random image

I'm currently working on a bot for my Discord server and I was wondering how to implement various image commands (for example, !cat, !meme) to make the bot send a random image each time the command is called.
Almost every bot I've seen has a feature like that but for some reason I can't seem to find a working way to do this in JDA. And any JDA example I found was either outdated or it simply didn't work, so I really hope someone can give me a hand here.
Here's a (very basic) example I already did, but the problem is that the pictures don't randomize with each call and just stay the same until I restart discord
public void sendCatImage() {
EmbedBuilder result= new EmbedBuilder();
result.setTitle("Here's a cat!");
result.setImage("http://thecatapi.com/api/images/get?format=src&type=png");
event.getChannel().sendMessage(result.build()).queue();
}
I'm using JDA Version 4.1.0_100, if it helps
Any help will be greatly appreciated!
Discord will cache the image based on the URL. You can append a random number as a query to prevent this:
public String randomize(String url) {
ThreadLocalRandom random = ThreadLocalRandom.current();
return url + "&" + random.nextInt() + "=" + random.nextInt();
}
...
result.setImage(randomize(url));
...
Furthermore, you can avoid discord updating the image by also uploading it alongside the embed. For that you first need to download the image and then upload it:
// Use same HTTP client that jda uses
OkHttpClient http = jda.getHttpClient();
// Make an HTTP request to download the image
Request request = new Request.Builder().url(imageUrl).build();
Response response = http.newCall(request).execute();
try {
InputStream body = response.body().byteStream();
result.setImage("attachment://image.png"); // Use same file name from attachment
channel.sendMessage(result.build())
.addFile(body, "image.png") // Specify file name as "image.png" for embed (this must be the same, its a reference which attachment belongs to which image in the embed)
.queue(m -> response.close(), error -> { // Send message and close response when done
response.close();
RestAction.getDefaultFailure().accept(error);
});
} catch (Throwable ex) {
// Something happened, close response just in case
response.close();
// Rethrow the throwable
if (ex instanceof Error) throw (Error) ex;
else throw (RuntimeException) ex;
}

JSon seralization error with Web Api

I was getting a self referenceing loop error "Self referencing loop detected for property 'ApplicationInstance' with type 'ASP.global_asax'" returned from a PUT call to a web api.
I added this to the web api config:
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.All;
Now I get a different error:
"The 'ObjectContent`1' type failed to serialize the response body for content type 'application/json; charset=utf-8
InnerException":ExceptionMessage":"Error getting value from 'ReadTimeout' on 'System.Web.HttpInputStream'.","ExceptionType":"Newtonsoft.Json.JsonSerializationException","StackTrace":" at Newtonsoft.Json.Serialization.DynamicValueProvider.GetValue(Object target)...
Per suggestion, I added the ".ReferenceLoopHandling.Ignore;" config. This fixesd the loop error, but not the 'can't read value' error.
I am having some trouble finding a cure for this one.
EDIT - Error is gone. I am hesitant to say yet if it is fixed, because I am not yet sure why the error was there in the first place. I made the error leave by changing my Put code in the web api. It was:
[HttpPut]
public IHttpActionResult Put([FromBody]RecipientDTO recipient)
{
try
{
repo.SaveUpdatedRecipient(recipient);
return Ok(this.GetById(recipient.RecipKey));
}
catch (Exception ex)
{
return BadRequest(ex.ToString());
}
}
and is now:
[HttpPut]
public HttpResponseMessage Put([FromBody]RecipientDTO recipient)
{
try
{
repo.SaveUpdatedRecipient(recipient);
return Request.CreateResponse(HttpStatusCode.OK);
}
catch (Exception ex)
{
ex.ToString();
//ValidationMethods.GetDbValidationExceptions(ex);
return Request.CreateResponse(HttpStatusCode.NotFound);
}
}
I am still working on the error handling portion, but at least the error is gone and the data is saved. I will update when I find out more. Any input is welcome.
To solve the issue add the below line of code to WebApiConfig.cs file in your webapi project
config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;

How can I correct an invalid key type in Parse Cloud Code?

We made a mistake in our client code where some users attempt to save a false boolean flag (by mistake) and others save a string to the same key in our Parse database.
I'm getting error code from Parse from everyone setting the false boolean as follows:
{"code":111,"error":"invalid type for key premiumType, expected string, but got boolean"}
Until we can release the next version of our client code, I want to intercept and correct this error IN CLOUD CODE. I'm trying this:
Parse.Cloud.beforeSave('GameScore', function(request, response) {
console.log("Entered function");
var premiumType = request.object.get("premiumType");
if (premiumType) {
request.object.set("premiumType", null);
response.success();
} else {
response.success();
}
});
But, the beforeSave function does not get entered unless the key type is correct, so I cannot modify the object here.
Are there any other locations where I can intercept this and modify the code in the cloud?

servicestack - caching a service response using redis

I have a servicestack service which when called via the browser (restful) Url ex:http://localhost:1616/myproducts, it works fine.
The service method has RedisCaching enabled. So first time it hits the data repository and caches it for subsequent use.
My problem is when I try calling it from a c# client via Soap12ServiceClient. It returns the below error:
Error in line 1 position 183. Expecting element '<target response>'
from namespace 'http://schemas.datacontract.org/2004/07/<target namespace>'..
Encountered 'Element' with name 'base64Binary',
namespace 'http://schemas.microsoft.com/2003/10/Serialization/'.
Below is my Client code:
var endpointURI = "http://mydevelopmentapi.serverhostingservices.com:1616/";
using (IServiceClient client = new Soap12ServiceClient(endpointURI))
{
var request = new ProductRequest { Param1 = "xy23432"};
client.Send<ProductResponse>(request);
}
It seems that the soapwsdl used is giving the problem, but I appear to have used the defaults as generated by servicestack..
Any help will be much appreciated.
Update
I was able over come this error by changing the cache code at the service end:
Code that returned error at client end:
return RequestContext.ToOptimizedResultUsingCache(this.CacheClient, cacheKey,
() =>
new ProductResponse(){CreateDate = DateTime.UtcNow,
products = new productRepository().Getproducts(request)
});
Code that works now:
var result = this.CacheClient.Get<ProductResponse>(cacheKey);
if (result == null)
{
this.CacheClient.Set<ProductResponse>(cacheKey, productResult);
result = productResult;
}
return result;
But I am still curious to know why the first method (RequestContext.ToOptimizedResultUsingCache) returned error at c# client?
But I am still curious to know why the first method (RequestContext.ToOptimizedResultUsingCache) returned error at c# client?
From what I can tell, the ToOptimizedResultUsingCache is trying to pull a specific format (xml, html, json, etc) out of the cache based on the RequestContext's ResponseContentType (see code here and here). When using the Soap12ServiceClient the ResponseContentType is text/html (not sure if this is correct/intentional within ServiceStack). So what ToOptimizedResultUsingCache is pulling out of the cache is a string of html. The html string is being returned to the Soap12ServiceClient and causing an exception.
By pulling directly out of the cache you are bypassing ToOptimizedResultUsingCache's 'format check' and returning something the Soap12ServiceClient can handle.
** If you are using Redis and creating your key with UrnId.Create method you should see a key like urn:ProductResponse:{yourkey}.html
Thanks for your response paaschpa.
I revisited the code and I was able to fix it. Since your response gave me the direction, I have accepted your answer. Below is my fix.
I moved the return statement from RequestContext to the response DTO.
Code which throws error when used via c# client (code was returning entire requestcontext):
return RequestContext.ToOptimizedResultUsingCache(this.CacheClient, cacheKey,
() =>
new ProductResponse(){CreateDate = DateTime.UtcNow,
products = new productRepository().Getproducts(request)
});
Fixed Code (return moved to response DTO):
RequestContext.ToOptimizedResultUsingCache(this.CacheClient, cacheKey,
() => {
return new ProductResponse(){CreateDate = DateTime.UtcNow,
products = new productRepository().Getproducts(request)
}
});

Kendo UI - how to implement Error Handling on WEB API, non MVC using Kendo Grid

My Scenario is I created a Web API that returns an Active Directory Object.
I have this WEB API function create Active Directory User and creates a user that returns Active Directory Object that contains First Name , Last Name, Email, UserName, Etc... What If it got an error how would I handle this?
I'm using Kendo Grid InLine Edit http://demos.kendoui.com/web/grid/editing-inline.html
I want to show the error message as a pop up window
How would I do that???
Options
try catch the error and put in the Active Directory Object as
Exception???
How can I capture this is Kendo UI?
Throw the response and get the error message and show it in the Kendo Grid
//HttpResponseMessage msg = new HttpResponseMessage(HttpStatusCode.OK)
//{
// Content = new StringContent(string.Format("No User with ID = {0}.{1}", businessObject.UserName, ex.InnerException.ToString() )),
// ReasonPhrase = "CustomerID Not Found in Database!"
//};
//throw new HttpResponseException(msg);
OR
//var message = string.Format("Error Message: {0}", taskCreateADUser.ADExceptionDescription);
//throw new HttpResponseException(
// Request.CreateErrorResponse(HttpStatusCode.OK, message));
Thanks,
MarcLevin
Whenever KendoUI binds via Ajax it relies on serialized version of ModelState sent in json response. Essentially if ModelState is not valid, the json response returned to the widget (grid in this case) will contain something like this:
{
"Errors":{
"PropA":{
"errors":[
"Error1",
"Error2"
]
},
"PropB":{
"errors":[
"FUBAR"
]
}
}
}
Essentially your WebAPI will need to return similar data structure if you want the grid to respond to it.
This is regarding your Option 2. You would need to apply the following correctly to your specific scenario. This is just a sample of a really simple parse of the response and displaying an alert if an error is detected. This sample expects a JSON object containing an array of Items. You could definitely apply more advanced handling once you have the basic idea down.
$("#grid").kendoGrid({
dataSource: {
schema: {
data: function(data) {
if (data.Items[0].substring(0,37) == "allmyerrormessagesstartwiththisphrase"){
alert(data.Items[0];
} else {
return data.Items;
}
}
},
transport: {
read: "http://myurl.com/something/"
}
}
}
);

Resources