I'm using the Altair Client to test some file uploads via Graphql. If I write out my query, and leave the variables blank, I get back an error response
Mutation:
mutation UploadCSV($fileData: Upload!) {
uploadCsv(fileData: $fileData) {
message
errors
successCount
}
}
Errors:
"message": "In argument \"fileData\": Expected type \"Upload!\", found null."
"message": "Variable \"fileData\": Expected non-null, found null."
This is exactly what I'd expect, because I haven't attached a file yet. So I follow the Altair instructions and pick a file, and give it the name fileData. Now when I click Send Request, I get the error "message": "No query document supplied", which is the error you get when no query/mutation has been sent. What am I doing wrong here?
Related
I am trying to use the Google Play Developer API to patch a subscription using the REST endpoint.
https://developers.google.com/android-publisher/api-ref/rest/v3/monetization.subscriptions/patch
The required query parameters are updatedMask and regionsVersion. When I click on the RegionsVersion for documentation it just says:
A string representing version of the available regions being used for
the specified resource.
https://developers.google.com/android-publisher/api-ref/rest/v3/RegionsVersion
Based on that description I'm not sure what kind of value it's expecting other than an object with a version property that is a string. When I omit the regionsVersion parameter is returns the following error:
{
"error": {
"code": 400,
"message": "Regions version should be set to the default value 2022/01.",
"status": "INVALID_ARGUMENT"
}
}
Does anyone have any idea or an example of how this required parameter is intended to be used?
I had the same issue and I found that since it's s JSON object you'll have to set its property like that with query params:
?updateMask=listings®ionsVersion.version=2022/01
This worked fine for me!
I am using resttemplate.exchange to invoke a URL and get response. But the issue is the response type varies when I successfully receives the output and if I get some error.
eg.
ResponseEntity<XXX[]> response = restTemplate.exchange(endPoint,HttpMethod.GET,req,
new ParameterizedTypeReference<XXX[]>() {},uriVariables);
If there is no issue with service and then output is in format of list. but if there is error like "NO DATA FOUND" then the response is in MAP. so whenever I have any issue with URL i get "404: null error" because my response type is unable to identify the error which is in MAP.
Could you please suggest what could be done as i can not change the response type of services.
Edit:: http://localhost:9090/data/getDetail?name=XXX
response [{"name":"XXX","Dept":"teaching","createdby":"YYY","createdDt":"06/09/2018"}]
when data not found case::http://localhost:9090/data/getDetail?name=YYY
response
{"response":"DATA NOT FOUND"}
This question already has answers here:
GraphQL - How to respond with different status code?
(5 answers)
Closed 3 years ago.
Previous When I made API server with RestAPI, I return data with HTTP status code.
So, Frontend receive status code from server, it determined request is success of fail.
I know that graphQL has error fields, and can refer it to solve this issue.
But I want to change response status code that send to client.
This way is correct and stable way?
Or, When use graphQL, do not change status code and just determine by error field is standard way?
Any suggestions would be appreciated :)
Thanks.
[...] do not change status code and just determine by error field is standard way?
YES do not manage errors using status codes, they are Http related and GraphQL aim at being protocol/framework agnostic so that everything you need should be inside your output.
As you said there can be an errors field in your response:
The errors entry in the response is a non‐empty list of errors, where each error is a map.
If no errors were encountered during the requested operation, the errors entry should not be present in the result.
The spec states that errors field entries can have a field named extensions:
GraphQL services may provide an additional entry to errors with key extensions. This entry, if set, must have a map as its value. This entry is reserved for implementors to add additional information to errors however they see fit, and there are no additional restrictions on its contents.
Using the extensions field you can add custom machine-readable information to your errors like the key code here.
{
"errors": [
{
"message": "Name for character with ID 1002 could not be fetched.",
"locations": [ { "line": 6, "column": 7 } ],
"path": [ "hero", "heroFriends", 1, "name" ],
"extensions": {
"code": "CAN_NOT_FETCH_BY_ID",
"timestamp": "Fri Feb 9 14:33:09 UTC 2018"
}
}
]
}
Apollo Prophecy
To make error management easier I created a codegen CLI that generate throwable errors classes for the server and facilitate error handling for client.
https://github.com/theGlenn/apollo-prophecy
I'm experimenting with building a GraphQL server and I'm trying to use the GraphiQL Chrome extension to play with it.
As soon as I set the endpoint to my server, http://localhost:3000/graphql, GraphiQL sends an empty query:
Request URL:http://localhost:3000/graphql
Request Method:POST
Status Code:200 OK
Remote Address:[::1]:3000
Referrer Policy:no-referrer-when-downgrade
I made it return an empty response, but then, I get this JavaScript error in Chrome:
react.min.js:14 Uncaught TypeError: Cannot read property 'length' of undefined
at GraphiQL.autoCompleteLeafs (chrome-extension://fkkiamalmpiidkljmicmjfbieiclmeij/ext/graphiql/graphiql.js:1060:33)
at GraphiQL._runEditorQuery (chrome-extension://fkkiamalmpiidkljmicmjfbieiclmeij/ext/graphiql/graphiql.js:1131:13)
at Object.r (chrome-extension://fkkiamalmpiidkljmicmjfbieiclmeij/ext/react.min.js:14:10134)
at i (chrome-extension://fkkiamalmpiidkljmicmjfbieiclmeij/ext/react.min.js:12:21911)
at Object.u [as executeDispatchesInOrder] (chrome-extension://fkkiamalmpiidkljmicmjfbieiclmeij/ext/react.min.js:12:22122)
at p (chrome-extension://fkkiamalmpiidkljmicmjfbieiclmeij/ext/react.min.js:12:18475)
at f (chrome-extension://fkkiamalmpiidkljmicmjfbieiclmeij/ext/react.min.js:12:18601)
at Array.forEach (native)
at r (chrome-extension://fkkiamalmpiidkljmicmjfbieiclmeij/ext/react.min.js:15:26156)
at Object.processEventQueue (chrome-extension://fkkiamalmpiidkljmicmjfbieiclmeij/ext/react.min.js:12:19721)
After that, GraphiQL doesn't work at all. I can type any query, click the play button and all it does is repeat the error:
What am I missing? Is GraphiQL expecting some sort of schema from a blank query?
I believe GraphiQL chrome extension requires an object response from the API. Try returning a blank object on emtpy requests to see if that solves it for you.
Looking at https://launchpad.graphql.com (which also uses GraphiQL) when submitting a blank request I get the following object back:
{
"code": 400,
"error": "Script returned an error.",
"details": "No query was provided in request body."
}
That is a descriptive response that you can use for debugging.
While building a new application on top of a graphql API we have run into the following problem:
We have a mutation with an input field whose type is a custom scalar with its own validation rules (in this case that the input is a well-formed email address).
On the client, the user of the app fills in a bunch of fields and hits submit. Currently, validation of the email address is handled by the GraphQL layer and aborts the mutation if it fails with a top-level error. Validation of all other fields is handled by the mutation, returning app-level errors in the mutation payload. The other validations in this case cannot be represented directly in the schema since they involve inter-dependent fields.
This behaviour is really unhelpful for the client: it now has to know about errors in two possible locations (top-level graphql errors, and the application errors in the mutation payload) and in two possible formats. It also means that other malformed fields whose malformed-ness is not represented in the GraphQL schema will not be reported until all the schema-level issues have been fixed, forcing the user to go through multiple rounds of "fix the error, hit submit, get another error".
What is the standard solution to this problem? Putting validations (quite complex in this case) on the client? Weakening the schema in order to group all relevant validations at the application layer?
The problem with error categorization
top-level graphql errors, and the application errors in the mutation payload
The distinction that you made between schema-level and application level errors is based on GraphQL type and mutation implementation. A client-side application usually expects a higher abstraction level of errors, i.e., it needs to distinguish user errors and system errors. That way it can mask the system errors as "internal error" and present the user errors as necessary. The developer also can inspect the set of system errors.
See a nice and concise article by Konstantin Tarkus on this: Validation and User Errors in GraphQL Mutations, whose approach I have followed in this answer.
A Not-so-standard-yet-makes-sense solution
To the best of my knowledge, there is no particular standard approach. However, you can try out the following approach.
First, having system-level errors in the top-level field errors of mutation response:
{
"data": {
"viewer": {
"articles": {
"edges": [
{
"node": {
"title": "Sample article title",
"tags": null
}
}
]
}
}
},
"errors": [
{
"message": "Cannot read property 'bar' of undefined",
"locations": [
{
"line": 7,
"column": 11
}
]
}
]
}
Second, putting user-level errors as a separate field errors in mutation payload. Example from the mentioned article:
{
data: {
user: null,
errors: [
'',
'Failed to create a new user account.',
'email',
'User with this email address was already registered.',
]
}
}
// The errors field is just an array of strings that follows this pattern —
// [argumentName1, errorMessage1, argumentName2, errorMessage2, … ]
The above approach enables the client to look for user errors in a defined format in a single place - the errors field of mutation payload. It also allows the client to receive all errors together.
This approach loses automatic validation of the mutation's input type. However, validation is not compromised as the input type's validation logic can be put in a separate function. This function will return validation errors as necessary, which will eventually be put in mutation payload's errors field.
By the way, thanks for the well-written question!
If you are using Apollo, you can easily multiplex the errors array in the graphql response for both graphql errors AND custom errors that are machine readable using this package:
https://github.com/thebigredgeek/apollo-errors