Bad Request Error 400 from API Response

  • 1
  • Problem
  • Updated 3 years ago
So I'm attempting to create a presentation through the core.presentation.add endpoint and I'm getting a very vague response that isn't in the API response format:

<HTML>
<HEAD>
<TITLE>Bad Request</TITLE>
</HEAD>
<BODY BGCOLOR="#FFFFFF" TEXT="#000000">
<H1>Bad Request</H1>
<H2>Error 400</H2>
</BODY>
</HTML>


I was able to perform this operation last night and my sdk is able to get a successful response from the core.presentation.get endpoint.

Photo of Shawn Marincas

Shawn Marincas

  • 220 Points 100 badge 2x thumb
  • confused

Posted 3 years ago

  • 1
Photo of Alexey

Alexey, Employee

  • 550 Points 500 badge 2x thumb
Hi Shawn,

I am having difficulties finding your request in our logs.

Would you be able to provide the complete text dump of the request you sent when you received this response?

Thanks,
Alexey
Photo of Shawn Marincas

Shawn Marincas

  • 220 Points 100 badge 2x thumb
I just tried it again just now and got the same thing, says my last request was 16-Sep-2015 15:15

I'm wary to include the full text request since it includes our companyId and the presentation layout we're creating, which I'm unsure if we should be sharing.
Photo of Shawn Marincas

Shawn Marincas

  • 220 Points 100 badge 2x thumb
One thing I've found confusing is that all the documents I've seen say that the `data` field of the request is a String, and so when I had success last night I was stringifying the data JSON.

When I did not do that I would get the error 

{ errors: 
   [ { domain: 'global',
       reason: 'badRequest',
       message: 'com.google.appengine.repackaged.org.codehaus.jackson.map.JsonMappingException: Can not instantiate value of type [map type; class java.util.LinkedHashMap, [simple type, class java.lang.String] -> [simple type, class java.lang.Object]] from JSON String; no single-String constructor/factory method (through reference chain: com.risevision.core.api.v1.EndpointRequestBody["data"])' } ],
  code: 400,
  message: 'com.google.appengine.repackaged.org.codehaus.jackson.map.JsonMappingException: Can not instantiate value of type [map type; class java.util.LinkedHashMap, [simple type, class java.lang.String] -> [simple type, class java.lang.Object]] from JSON String; no single-String constructor/factory method (through reference chain: com.risevision.core.api.v1.EndpointRequestBody["data"])' }


I get this when trying to use core.display.add as well, whether I stringify the `data` field or not.

Photo of Alexey

Alexey, Employee

  • 550 Points 500 badge 2x thumb
Shawn.

I see one request to create a presentation at 15:15 from ofabXXXXX@gmail.com for company Id= 74XXXXXXXXXX83c and the response was 200 (OK). Is that the request you are referring to?

The only situation when adding presentation fails with 400 (Bad Request) on our side is when the presentation name is empty or not defined.

There may be other situations when Google Endpoints would consider the request to be bad and return error response before our server even sees the request. I wonder if this is what happened earlier.

Have you tried submitting your request via Google API Explorer (https://rvaserver2.appspot.com/_ah/ap...) to see if you get more details regarding the error?

Thanks,
Alexey
Photo of Alexey

Alexey, Employee

  • 550 Points 500 badge 2x thumb
Shawn,

Do you get the error when you run the example code from https://help.risevision.com/developer... with your data?

Thanks,
Alexey
Photo of Shawn Marincas

Shawn Marincas

  • 220 Points 100 badge 2x thumb
Nope, that's not me, our companyId is f3fxxxxxxxxx910 and the email domain is thinaire.net

I'm definitely including a name field and what's weird is that I'm getting the HTML response instead of the JSON response

I can definitely see there being a possible Google problem... the layout field is extremely large, so I'm wondering if there is some sort of request size limit?

I'll out the API Explorer and see if that gives me something different
Photo of Shawn Marincas

Shawn Marincas

  • 220 Points 100 badge 2x thumb
I was able to make the request successfully through http://rise-vision.github.io/core-api/

What are your thoughts on the stringifying the data field, or the request size?  If I don't stringify the data object I get the error below, which is at least a valid error from your API I think
 
{ errors: 
   [ { domain: 'global',
       reason: 'badRequest',
       message: 'com.google.appengine.repackaged.org.codehaus.jackson.map.JsonMappingException: Can not instantiate value of type [map type; class java.util.LinkedHashMap, [simple type, class java.lang.String] -> [simple type, class java.lang.Object]] from JSON String; no single-String constructor/factory method (through reference chain: com.risevision.core.api.v1.EndpointRequestBody["data"])' } ],
  code: 400,
  message: 'com.google.appengine.repackaged.org.codehaus.jackson.map.JsonMappingException: Can not instantiate value of type [map type; class java.util.LinkedHashMap, [simple type, class java.lang.String] -> [simple type, class java.lang.Object]] from JSON String; no single-String constructor/factory method (through reference chain: com.risevision.core.api.v1.EndpointRequestBody["data"])' }
Photo of Shawn Marincas

Shawn Marincas

  • 220 Points 100 badge 2x thumb
So I think the size of the request might have been the problem... I did some HTML minification on the layout string before sending it, and now I'm only getting this other 400 error

I get the same thing now whether or not I use JSON.stringify on the `data` key value... really can't figure out how I got it to work last night.

Can you see my latest requests and see any JSON issues with them?
Photo of Alexey

Alexey, Employee

  • 550 Points 500 badge 2x thumb
Shawn,

JSON issues are handled by Google infrastructure, I am afraid.

I can see your requests in the server logs and 400 errors being returned but I don't see the contents of your requests because they never reach my code, Google intercepts them.

If requests sent via our sample code are successful, can you just compare your code with ours to see what the differences are? (I am assuming you are using JavaScript for your client).
Photo of Shawn Marincas

Shawn Marincas

  • 220 Points 100 badge 2x thumb
I am, but I'm using node with this older version of the the google-api-nodejs-client (newer versions don't have methods to do discovery on google cloud endpoints)

https://github.com/google/google-api-nodejs-client/tree/72a3c8543a5665b3903889ccad27a27289207f02

It seems like I do need to use JSON.stringify on the data key and the module generates a URL of the format https://rvaserver2.appspot.com/_ah/api/core/v1/presentation?companyId=xxxxx&data=[ URL-Encoded Stringified Data Object ]

Does that sound right for core.presentation.add requests?
Photo of Alexey

Alexey, Employee

  • 550 Points 500 badge 2x thumb
I don't think this is going to work in general case because the "data" would include the presentation HTML layout and it is likely to be long enough to exceed max URL length.

I think you need to send "data" in the body of the request.
Photo of Shawn Marincas

Shawn Marincas

  • 220 Points 100 badge 2x thumb
Yep, so it turns out that this google-api-nodejs-client library that was I using didn't work the same the gapi client library that you guys have in your examples.

It actually takes two objects, one for the querysting params with the `companyId` and `fields` parameters and then another for the request body with the `data` parameters.

Thanks for your help Alexey!

I think I'm going to wrap all this up into a node-risevision-sdk module to help out anyone else who ends up trying to implement it.  I'll make another post when I've worked out any more bugs and published it to NPM.
Photo of Justin

Justin, Employee

  • 2,526 Points 2k badge 2x thumb
Shawn,

Let us know how this works out for you!

Justin