Nishil Faldu
Nishil Faldu•10mo ago

Doc<'tablename'>

so i tried to do the Doc<'tablename'> directly in the query handler , 'Doc' only refers to a type, but is being used as a value here. why do you think is that?
20 Replies
ballingt
ballingt•10mo ago
Sounds like a TypeScript syntax issue. Can you show the code? likely you need to name the parameter
Nishil Faldu
Nishil FalduOP•10mo ago
import type { Doc } from "./_generated/dataModel";

export const updateListingById = mutation({
args: {
id: v.id("listings"),
listing: Doc<"listings">,
},
handler: async ({ db }, { id, listing }) => {
const existingListing = await db.get(id);

if (!existingListing) {
throw new ConvexError(
"Listing not found. Please check the ID and try again.",
);
}

await db.patch(id, listing);
},
});
import type { Doc } from "./_generated/dataModel";

export const updateListingById = mutation({
args: {
id: v.id("listings"),
listing: Doc<"listings">,
},
handler: async ({ db }, { id, listing }) => {
const existingListing = await db.get(id);

if (!existingListing) {
throw new ConvexError(
"Listing not found. Please check the ID and try again.",
);
}

await db.patch(id, listing);
},
});
ballingt
ballingt•10mo ago
Ah sorry, I was thinking TypeScript syntax. You want the Convex validator syntax.
Nishil Faldu
Nishil FalduOP•10mo ago
my bad if I wasn't clear
ballingt
ballingt•10mo ago
no you're good, this is the more obvious thing to want The easiest way to do this now is to define the validator outside of the schema expression and give it a name and then import it
ballingt
ballingt•10mo ago
Here's just the article for you, the first solution presented is what I mean by "define the validator outside the defineSchema expression" https://stack.convex.dev/argument-validation-without-repetition
Argument Validation without Repetition
A few more advanced techniques & helpers to further reduce duplication and accelerate your Convex workflow.
ballingt
ballingt•10mo ago
oh actually this is the more advanced one, https://stack.convex.dev/types-cookbook looks like a better place to start
Types and Validators in TypeScript: A Convex Cookbook
It can be tough to wrangle types to behave how you want them to. Thankfully, Convex was designed to make the experience with types perfect. Learn why ...
Nishil Faldu
Nishil FalduOP•10mo ago
Ah that does make me feel stupid lol. I was hoping for a one line type for validator from somewhere 😂. I appreciate your help now that I am here I might as well ask another question. So for patch, what if it fails - what's the best way of checking that and throwing error to the user? (would a simple try-catch be fine?)
ballingt
ballingt•10mo ago
Ah sorry I missed this! @Nishil Faldu what kind of error do you want to throw? And I'm confused about why you want the try/catch if you want to throw an error
Nishil Faldu
Nishil FalduOP•10mo ago
Like so far I have just been doing
try {
// patch here
} catch(error) {
// report error and log error
}
try {
// patch here
} catch(error) {
// report error and log error
}
was wondering if there was a better approach
ballingt
ballingt•10mo ago
If that's all you're doing, you could skip that — because the patch will throw an error fi it fails and e.g. Sentry will receive the error without you throwing your own https://docs.convex.dev/production/integrations/exception-reporting But if you want to do your own validation first say, or you want to display a specific error to the user, they what you're doing looks reasonable. THen you're planning to catch the error on the client side? Ah Sentry integration is just for the pro plan, but regardless you'll see the error in your logs. But if you're trying to log the error to another service or put it in a DB table, then yeah catching it and doing that could make sense
Nishil Faldu
Nishil FalduOP•10mo ago
that's pretty cool
ballingt
ballingt•10mo ago
Roughly what you want is already what will happen
Nishil Faldu
Nishil FalduOP•10mo ago
yeah I have been thinking of going pro for this project once I push it to prod
ballingt
ballingt•10mo ago
but if you want to do something special, then yeah catching the error and then doing whatever you want is fine
Nishil Faldu
Nishil FalduOP•10mo ago
sounds good. Thanks for your help
ballingt
ballingt•10mo ago
If your goal is to use the error to deliver specific information to a browser, then note that you need to throw a special error, a ConvexError, to use the error to send data to the frontend normal errors throwin in a Convex function will be visible in dev but in prod all the details will be stripped away https://docs.convex.dev/functions/error-handling/application-errors Note that normally the db.patch() failing and throwing an error would cause the entire mutation to be aborted, rolling back any other changes in the mutation. But if you catch the error, that's not what happens — the other DB writes you made in the mutation function will still take effect so if that's not your goal, be sure to throw an error again after you do whatever it was you wanted to do in the catch(e) { ... }
Nishil Faldu
Nishil FalduOP•10mo ago
oooohh i see. that's very helpful to know. i'd have totally missed that
try {
await db.patch(id, user);
} catch (error) {
console.log(error);
throw new ConvexError(
"We encountered an issue updating the user. Please try again later.",
);
}
try {
await db.patch(id, user);
} catch (error) {
console.log(error);
throw new ConvexError(
"We encountered an issue updating the user. Please try again later.",
);
}
so doing this will still rollback any other changes in the mutation? (because I threw an error in catch block?)
ballingt
ballingt•10mo ago
Yep!
Nishil Faldu
Nishil FalduOP•10mo ago
perfect. I think that was a good bunch of information. thanks again!

Did you find this page helpful?