Manual rollback / error paths in mutations
I’d like to insert specific “error event” documents into the database whenever certain mutations fail. These are used to provide observability to the customer, and not just the developers that can access the db logs.
Is there a way to manually rollback on error and continue the mutation in an error path?
I understand a possible solution might be to use and action catching the mutation and invoking another mutation on error. Is there any other “mutation only” way? (From what I understand actions are a bit heavier so if possible doing everything in a mutation would be great)
3 Replies
Thanks for posting in <#1088161997662724167>.
Reminder: If you have a Convex Pro account, use the Convex Dashboard to file support tickets.
- Provide context: What are you trying to achieve, what is the end-user interaction, what are you seeing? (full error message, command output, etc.)
- Use search.convex.dev to search Docs, Stack, and Discord all at once.
- Additionally, you can post your questions in the Convex Community's <#1228095053885476985> channel to receive a response from AI.
- Avoid tagging staff unless specifically instructed.
Thank you!
Technically manual rollback is an option, but I can't imagine it being a feasible option as a general strategy. You'd probably have to individually try/catch each operation that needs to be potentially rolled back, and have correct logic for reversing previous operations within the mutation.
One option is to use the Sentry integration and send a webhook back to a Convex http action on error, where it can be recorded to the db. Sentry webhook doc here: https://docs.sentry.io/organization/integrations/integration-platform/webhooks/
Webhooks
Learn more about Sentry's integration platform webhooks and how they allow your service to receive requests about specific resources, such as installation, issues, and alerts.
This could maybe fall into an infinite loop given the right error scenarios, though, so you'd want to be careful there.
Hmm you know what might work, you could use
ctx.runMutation()
to run a mutation from a mutation, and try/catch the inner mutation run. That way the inner mutation can roll back if it fails, and the outer mutation can record the error to the db.
This means every mutation is two mutations minimum, but still better than using actions.