Mutations not returning any data or errors from AppSync server [Reproducible Repo Included]
See original GitHub issueEDIT: I have created a repository here where I was able to reproduce the issue on a small-scale project.
I am trying to use the AWSAppsyncClient in my React web application and I have come across an issue that I have been trying to solve for days to no avail.
I cannot seem to be able to return any data from any of the Mutations I have written. I have tested all of my mutations on the AppSync console and I can confirm all of them do return data and errors. The problem seems to lie within the Client itself (or maybe something is wrong with my setup).
For example, when I call this deleteEntity Mutation I want to display the error message to the screen.
<Mutation
mutation={DELETE_ENTITY}
variables={{ _id: record._id, tpID: this.props.orgData.transporter._id }}
onCompleted={(data) => {console.log('delete data', data); message.success(`Delete successful (${data.deleteEntity})`)}}
onError={(error) => {console.error(error); message.error('Delete failed: ' + error.message)}}
refetchQueries={[
{query, variables: {tpID: this.props.orgData.transporter._id}}
]}
>
{
(deleteEntity) => (
<Tooltip title="Delete">
<Popconfirm placement="left" title="Are you sure you want to delete this?" okText="Delete" onConfirm={() => deleteE
<Button type="danger" size="small" shape="circle" icon="delete" />
</Popconfirm>
</Tooltip>
)
}
</Mutation>
For this, and all similar mutations, no matter what, the data.mutationName returned from the mutation is always null, and error is always undefined even though this mutations do return data on the AppSync console. This even affects the onError callback function that the react-apollo Mutation component offers.
In my Client setup, I have included an error link as per the Apollo docs so I can see the errors in the console.
When any mutation is run, I do get GraphQL errors in the console like so:
It seems that somehow these errors are failing to make it back to the Mutation component.
Here is how I am setting up the AppSync Client:
const stateLink = withClientState({
cache,
defaults,
resolvers: _.merge(transporterResolv, contractsResolv, organizationResolv, customerResolv),
typeDefs: _.concat(transporterSchem, customerSchem)
});
const appSyncLink = createAppSyncLink({
...config.appSync,
auth: {
...config.appSync.auth,
jwtToken: async () => (await Auth.currentSession()).getIdToken().getJwtToken(),
},
disableOffline: true
});
const errorLink = onError(({ graphQLErrors, networkError, operation, forward }) => {
if (graphQLErrors) {
for (let err of graphQLErrors) {
console.log('[Graphql Error]', err);
switch (err.errorType) {
case 'UnauthorizedException':
// error code is set to UNAUTHENTICATED
// when AuthenticationError thrown in resolver
// modify the operation context with a new token
return new Observable(async observer => {
try{
// const creds = await Auth.currentUserCredentials();
// creds.refresh(err => {throw Error(err)});
const idToken = await Auth.currentSession().idToken;
console.log('currentSession', await Auth.currentSession());
const oldHeaders = operation.getContext().headers;
operation.setContext({
headers: {
...oldHeaders,
authorization: idToken.jwtToken,
},
});
const subscriber = {
next: observer.next.bind(observer),
error: observer.error.bind(observer),
complete: observer.complete.bind(observer)
}
forward(operation).subscribe(subscriber);
}catch(error){
console.error('ID Token refresh failed', err)
observer.error(error)
}
})
}
}
}
if (networkError) {
console.log(`[Network error]: ${networkError}`);
}
}
);
const link = ApolloLink.from([errorLink, stateLink, appSyncLink])
const AppSyncClientOptions = {
link
}
const client = new AWSAppsyncClient({}, AppSyncClientOptions);
Dependencies from packages.json
"dependencies": {
"antd": "^3.7.2",
"apollo-boost": "^0.1.15",
"apollo-cache-inmemory": "^1.2.9",
"apollo-link": "^1.2.2",
"apollo-link-error": "^1.1.0",
"apollo-link-state": "^0.4.1",
"aws-amplify": "^1.0.2",
"aws-appsync": "^1.3.4",
"aws-appsync-react": "^1.1.4",
"aws-sdk": "^2.302.0",
"graphql": "^0.13.2",
"graphql-tag": "^2.9.2",
"lodash": "^4.17.10",
"moment": "^2.22.2",
"qs": "^6.5.2",
"react": "^16.4.1",
"react-apollo": "^2.1.11",
"react-dom": "^16.4.1",
"react-router-dom": "^4.3.1",
"react-scripts": "1.1.4",
"redux": "^4.0.0",
"redux-persist": "^5.10.0"
},
Issue Analytics
- State:
- Created 5 years ago
- Comments:22 (7 by maintainers)
Top GitHub Comments
I was facing this same issue for a while until I found that there was a mismatch between the data I was sending to the server and the graphql input type defined in our AWS AppSync schema!
Our input type had fields that were arrays of strings or arrays of the AWSJSON data type and I was accidentally sending an empty string in one of those fields which caused data creation/persistence to fail and in turn the server was ALWAYS returning null instead of all the fields I expected to get back from the mutation.
I would imagine this could affect both queries and mutations if the data types your input doesn’t match EXACTLY what the schema defines and is not an issue with the aws appsync sdk itself.
It’s too bad the server doesn’t throw any exceptions. I suspect quite a few developers are seeing this behavior which is caused by a data to schema mismatch and an error response from the server would make that issue clear as day. Maybe those errors are being buried somewhere due to our resolvers…
@jrounsav Thanks for the workaround. Setting disableOffline to true does solve the problem. I was actually already setting disableOffline to true, but I was putting it in the createAppSyncLink instead of the AWSAppSyncClient options.
This works