djbalin
djbalin4d ago

Calling `ctx.runQuery` from `query`

I seem to have my world shaken by Convex almost every day (in a good way)! I always thought ctx.runQuery/runMutation was only possible from actions, and that calling a query from within a query was not possible, but that regular TS helper functions should be employed (e.g. as @erquhart mentions here https://discord.com/channels/1019350475847499849/1216003221445939330/1216033039247867984). I just found out that it is indeed possible by just using ctx.runQuery. That comes with this warning/info: often you can call the query's function directly? Is this what you mean/propose?:
export const getAllCategories = authQuery({
handler: async (ctx) => {
return ...
},
})

export const testQuery = authQuery({
handler: async (ctx) => {
const categories = await getAllCategories(ctx, {})
},
})
export const getAllCategories = authQuery({
handler: async (ctx) => {
return ...
},
})

export const testQuery = authQuery({
handler: async (ctx) => {
const categories = await getAllCategories(ctx, {})
},
})
3 Replies
Convex Bot
Convex Bot4d ago
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!
lee
lee4d ago
Here's a draft of part of the upcoming release notes, which should help with guidance. ( cc @ballingt ) Warn on direct Convex function call. This adds a console.warn whenever a Convex Function (mutation, query, action, internalMutation, etc.) is called directly
export const foo = mutation(...);

await foo(ctx);

export const foo = mutation(...);

await foo(ctx);

because this pattern causes problems and there are easy workarounds. The problems here: 1. Arguments and return values aren't validated despite the presence of validators at the function definition site. 2. Functions called this way unexpectedly lack isolation and atomicity. Convex functions may be writting assuming they will run as independent transactions, but running these function directly breaks that assumption. 3. Running Convex functions defined by customFunctions like triggers can cause deadlocks and other bad behavior. There are two options for how to modify your code to address the warning: 1. call the handler directly, after refactoring it out as a helper function. 2. use ctx.runMutation, ctx.runQuery, or ctx.runAction() instead of calling the function directly. This has more overhead (it's slower) and counts as a Convex Function call for billing purposes but you gain isolation and atomicity. See https://docs.convex.dev/production/best-practices/#use-helper-functions-to-write-shared-code for more. For now running functions this way only logs a warning.
Best Practices | Convex Developer Hub
Here's a collection of our recommendations on how best to use Convex to build
lee
lee4d ago
I saw @erquhart typing and then stop, so i'll mention that we're looking into this behavior as inspired by his comment here https://discord.com/channels/1019350475847499849/1307399827033690233/1307404413438132345