App Engine manages what's returned as error JSON on Cloud Endpoints. When I throw ServiceException which Google supplies, I pass it statusCode and statusMessage:
public ServiceException(int statusCode, String statusMessage) {
super(statusMessage);
this.statusCode = statusCode;
this.reason = null;
this.domain = null;
}
App Engine then returns this JSON to the caller in the error response:
{
"error": {
"errors": [
{
"domain": "global",
"reason": "required",
"message": "The statusMessage I gave it."
}
],
"code": 401,
"message": "The statusMessage I gave it."
}
}
I would like to extend the response with an extra field, e.g. for an application error code which tells the client what went wrong (message should be human readable).
I'm not so deep into Java servlets and internal workings of this, but I have tried to catch the response and modify it, which worked for a 200 response, but not for an error response. Any ideas?
Based on what you are requesting, I would suggest you take a look at how the ServiceException class works on the Java endpoints-framework.
Here you can check how the exceptions are being handled and, based on this, extend the error JSON that is returned to suit your needs, that is, that anyone can understand why his run failed.
Related
I'm using Firebase Admin SDK Java API v6.12.2.
I call FirebaseAuth.getInstance().generatePasswordResetLink(email, actionCodeSettings) to generate a password reset link for users. If the email isn't registered, I get a big blob of text with embedded JSON from e.getMessage().
The looked at the FirebaseAuthException doc and it only exposes one method e.getErrorCode(), which in this case returns internal-error.
I can certainly parse this text to look for "EMAIL_NOT_FOUND" and translate it into a user-friendly message. But isn't that a very clumsy error message? At least, there should have been methods to return the error code 400, and a simple String message, and the details could go into a JSON object.
What is the recommended approach here by the Firebase team and how are other developers handling it?
Output of e.getMessage():
Unexpected HTTP response with status: 400; body: {
"error": {
"code": 400,
"message": "EMAIL_NOT_FOUND",
"errors": [
{
"message": "EMAIL_NOT_FOUND",
"domain": "global",
"reason": "invalid"
}
]
}
}
I am trying to build a rest api that should consume json/x-application data. Now I have looked into two libraries javax.json-api and org.json for handling the data.
Example JSON:
{
"error": "false",
"error_msg": "",
"version": "1.13.10",
"result": {
"malware": {
"finding1": {
"file": "/path/to/filep",
"malware": "{HEX}r2h.malware.blue.44"
}
}
},
"newest_version": "1.13.10"
}
If I now consume this with javax JsonObject, it will work and I can go on with my code. BUT, if i instead post this data and I use org.json.JSONObject I will receive response at the client:
Unrecognized field "error" (class org.json.JSONObject), not marked as ignorable
Tried to find responses on the web, but I didnt step over anything that explains this?
Regards and Thanks
Well,
I do not really know if there is a solution for this. Eventually the REST architectural style does not support JSONObject (org.json.JSONObject). However, the workaround is pretty easy, just consume the json as a String (still you can declare HTTP Request to enforce the type application/json).
So this could look like the following:
#Path("/myendpoint")
#POST
#Consumes(MediaType.APPLICATION_JSON)
public String receiveRequest(String json) {
JSONObject jo = new JSONObject(json);
...
}
First off all your json is valid json. Second thing you are getting a error in response, it means error is not in your code. And third thing the error is "Unrecognized field" it means the POJO class inside the client code does not contain field "error".
When I check my logs on my GAE app, I can see every so often a warning message like that:
com.google.api.control.Client flushAndScheduleReports: direct send of a report request failed because of endpoints.repackaged.com.google.api.client.http.HttpResponseException: 400 (Client.java:354)
{
"error": {
"code": 400,
"message": "Precondition check failed.",
"errors": [
{
"message": "Precondition check failed.",
"domain": "global",
"reason": "failedPrecondition"
}
],
"status": "FAILED_PRECONDITION"
}
}
However it seems the client app works as expected and I don't understand what it means.
If you have a low traffic API, this typically will happen if too long goes in between requests. The app will work as expected, but metric reporting may be off. This is because metrics are aggregated and reported every so many requests, unless you're running a backend instance.
i am trying to use google api explorer to first try to insert an object to google cloud storage.
the request looks like
POST https://www.googleapis.com/storage/v1/b/visionapibucket/o?key={YOUR_API_KEY}
{
"contentType": "image/jpeg",
"uploadType": "media",
"path": "/upload/storage/v1/b/visionapibucket/o"
}
but i see the error as
400 HTTP/2.0 400
- Show headers -
{
"error": {
"errors": [
{
"domain": "global",
"reason": "required",
"message": "Required"
},
{
"domain": "global",
"reason": "wrongUrlForUpload",
"message": "Upload requests must include an uploadType URL parameter and a URL path beginning with /upload/",
"extendedHelp": "https://cloud.google.com/storage/docs/json_api/v1/how-tos/upload"
}
],
"code": 400,
"message": "Required"
}
}
not sure what i am missing. please advise
Looks like a bug on the website. It doesn't seem like the explorer supports media.
The request it generated looks like:
POST https://www.googleapis.com/storage/v1/b/visionapibucket/o?key={YOUR_API_KEY}
But a proper upload request would look like:
POST https://www.googleapis.com/upload/storage/v1/b/visionapibucket/o?key={YOUR_API_KEY}&uploadType=media&name=myfile.jpeg
You'll also want to include a "Content-Type" header specifying that it's a JPEG image.
There's a guide on the various ways to upload objects using the JSON API here. The specific type you're looking for is like a simple upload.
I have to post json to api_url for login.
{
"username":"testre","password":"password"
}
When I use postman to check this api, it reply successful authentication like below.
{
"status": "success",
"code": 200,
"message": "username, password validated.",
"data": [
{
"password": "password",
"username": "testre"
}
],
"links": [
{
"rel": "self",
"link": "http://localhost:2222/pizza-shefu/api/v1.0/customers/login/"
},
{
"rel": "profile",
"link": "http://localhost:2222/pizza-shefu/api/v1.0/customers/testre"
}
]
}
For an unauthorized json like below.
{
"status": "unauthorized",
"code": 401,
"errorMessage": "HTTP_UNAUTHORIZED",
"description": "credentials provided are not authorized."
}
Previously I code to retrieve it using java. But now I want to refactor it using RestTemplate in spring. The problem is every example I read is written for fixed number of variables https://spring.io/guides/gs/consuming-rest/. Here I get different numbers of variable according to the login success status. I am new to spring so I'm confused in creating the class for login reply which we get from rest template. (Such as this in the example Quote quote = restTemplate.getForObject("http://gturnquist-quoters.cfapps.io/api/random", Quote.class); But I need to return a json object). I couldn't figure out how to write the RestTemplate part.
As suggested by #Andreas:
Add the superset of all fields for all possible responses
Identify the set of fields that are mandatory for every response and make them required
Make the rest of the fields as optional
Upon receveiving a response, check the status code and implement your logic accordingly.
If you are using Jackson for Deserialization, all fields are optional by default (see this question)