Debugging an offline mutation issue. Need help in deeply understanding the mutation flow. #1047
-
I'm still tacking the issue of a mutation I'm testing causing all future network calls to be skipped. So I've created a VERY simple mutation. The client is created with type Mutation {
echo(message: String!): String
} Mutation: {
echo(parent, args, context, info) {
const { message } = args
return message
} The method: export async function runEcho() {
const mutation = `
mutation {
echo(message: "Hello World")
}
`
const result = await client.mutation(mutation).toPromise()
return result
} I have nothing set up in optimistic or updates for this mutation. When I run it with network set to offline I get: {
"error": {
"name": "CombinedError",
"message": "[Network] Failed to fetch",
"graphQLErrors": [],
"networkError": {}
},
"operation": {
"key": 1925573437,
"query": {
"kind": "Document",
"definitions": [
{
"kind": "OperationDefinition",
"operation": "mutation",
"variableDefinitions": [],
"directives": [],
"selectionSet": {
"kind": "SelectionSet",
"selections": [
{
"kind": "Field",
"name": {
"kind": "Name",
"value": "echo"
},
"arguments": [
{
"kind": "Argument",
"name": {
"kind": "Name",
"value": "message"
},
"value": {
"kind": "StringValue",
"value": "Hello World",
"block": false
}
}
],
"directives": []
}
]
}
}
],
"__key": 1925573437
},
"variables": {},
"operationName": "mutation",
"context": {
"url": "http://localhost:4000/graphql",
"preferGetMethod": false,
"requestPolicy": "cache-and-network"
}
}
} There is nothing queued up in metadata. My questions: Is this expected behavior, that a mutation as defined above will not be queued up in offline mode? |
Beta Was this translation helpful? Give feedback.
Replies: 8 comments 2 replies
-
The prerequisite is for it to be an optimistic mutation. An optimistic mutation is one that uses at least one field on the In the absence of this definition, the mutation behaves normally. That means it won’t be altered by the The reason for that is that we’ve made one assumption: If you have a non-optimistic mutation then the cache won’t change because no updates are possible. So the only possible implementation path is to display this error to the user, which means no special behaviour applies. |
Beta Was this translation helpful? Give feedback.
-
Thanks! I ended up being sidetracked with other work after I posted this but I'll continue testing with your new information to see if I can find out what's happening. |
Beta Was this translation helpful? Give feedback.
-
Okay, @kitten. So I have a further clarification question. I've added an optimistic response: optimistic: {
echo(variables, cache, info) {
console.log("The echo optimistic response was invoked")
return {
echo: "hi there"
}
}
}, and I added logging to the mutation call export async function runEcho() {
const mutation = `
mutation {
echo(message: "Hello World")
}
`
console.log("------------------ Starting echo mutation --------------------")
try {
const result = await client.mutation(mutation).toPromise()
console.log(
"------------------ Echo mutation complete --------------------"
)
return result
} catch (e) {
console.log(e)
console.log("------------------ Echo mutation error --------------------")
}
} The mutation now queues up in offline mode But when I go back into online mode, the call to I want to confirm this is expected behavior as I'm trying to figure out exactly where network calls are being broken. |
Beta Was this translation helpful? Give feedback.
-
More logging and I've confirmed that the Promise is never resolved. export async function runEcho() {
const mutation = `
mutation {
echo(message: "Hello World") {
message
}
}
`
console.log("------------------ Starting echo mutation --------------------")
try {
const preliminaryResult = client.mutation(mutation)
console.log(preliminaryResult)
console.log(preliminaryResult.toPromise())
const result = await preliminaryResult.toPromise()
console.log(
"------------------ Echo mutation complete --------------------"
)
console.log(result)
return result
} catch (e) {
console.log(e)
console.log("------------------ Echo mutation error --------------------")
}
} Is this right or is the stream still waiting in spite of the if (operationName === 'mutation') {
// A mutation is always limited to just a single result and is never shared
return pipe(
operationResults$,
onStart<OperationResult>(() => this.dispatchOperation(operation)),
take(1)
);
} |
Beta Was this translation helpful? Give feedback.
-
So if you're offline, issue the mutation, and then go back online the promise should resolve. Just a quick note again that those are fire-and-forgets so I wouldn't rely on that.
Regarding that, have you resolved this? #1042 (comment) If the metadata is not empty and never changes (i.e. always contains that failed mutation) then you'll have to check why |
Beta Was this translation helpful? Give feedback.
-
Okay. I whacked everything including removing node_modules and all traces of urql from package.json and then readding via yarn. I noticed there had been another update to graphcache too. That did take care of the system not running the mutation on going online. I'm still not seeing the optimistic response though, and the promise still does not resolve until I go back online. Is that to be expected? That the mutation will hang part way until it is completed? |
Beta Was this translation helpful? Give feedback.
-
Sorry I didn't close this properly. It is no longer a problem. I've been working the past several days testing all the possible variations and URQL is performing like a champ. I'm currently integrating URQL into our authentication/encryption system and then will be integrating that into the full application. |
Beta Was this translation helpful? Give feedback.
-
I'll check with the project sponsors and see if it's okay to release the information. The system is robust enough that I'm not overly concerned with people seeing the internals (it uses SubtleCrypto for the libraries), but I want those who are paying for it to have the final say. |
Beta Was this translation helpful? Give feedback.
The prerequisite is for it to be an optimistic mutation. An optimistic mutation is one that uses at least one field on the
Mutation
root type that has an optimistic updater defined in thecacheExchange
config.In the absence of this definition, the mutation behaves normally. That means it won’t be altered by the
offlineExchange
, it won’t have a potential network error intercepted, and it won’t be queued up to be rerun once you’re offline again.The reason for that is that we’ve made one assumption: If you have a non-optimistic mutation then the cache won’t change because no updates are possible. So the only possible implementation path is to display this error to the user, which means no …