Get the value that was attempted to be parsed in an Arg

Hiya folks, I have the following code, where I determine if the arg is either of my custom type (working), or if it's a server member. If it is neither, I want to throw out an error that I can handle, but as part of handling that error, I'd like to know the value that was attempted to be parsed.
battleArgs.combatant2 = await args.pick(DrpgNpcArg).catch(
async (e1) =>
await args.pick("member").catch((e2) => {
throw new Error(`${value} did not rsolve to an NPC or a Character.`);
}),
);
battleArgs.combatant2 = await args.pick(DrpgNpcArg).catch(
async (e1) =>
await args.pick("member").catch((e2) => {
throw new Error(`${value} did not rsolve to an NPC or a Character.`);
}),
);
in this example, value (inside the Error) doesn't exist, but I think it's pretty clear what I'm trying to do. I know that I could make an arg type that returns either an Npc or a Guild Member, and use parameter in the Args.error similar to what I do here... But I'd rather not have to make a brand new arg type for trying to do something like this. Any pointers?
Solution:
Hiya folks, I have the following code, where I determine if the arg is either of my custom type (working), or if it's a server member. If it is neither, I want to throw out an error that I can handle, but as part of handling that error, I'd like to know the value that was attempted to be parsed. ```ts...
Jump to solution
7 Replies
Favna
Favna15mo ago
Use Args.make for local art types that don't need to be in the argument folder Or use pickResult which gives a result class back you can manipulate however you want.
Spinel
Spinel15mo ago
<::746069730170896405> Sapphire docs results: @sapphire/framework / Class: Args / make​ <::746069730170896405> Sapphire docs results: @sapphire/ / Module: @sapphire/result
Bejasc
Bejasc15mo ago
is there a "shorter" way to use args.make? I do use that for the NPC arg, but if possible I'd like to avoid making a new arg type for this specific case, as I'm sure I'll have many more like it. I guess there's some way to do this 'inline'? Right now, I have this in it's own args folder.
export default Args.make<Npc>(async (parameter, { argument }) => {
const npc = await NpcService.getNpc(parameter);

if (npc) {
Logger.trace(`DrpgNpcArg MATCH: ${npc.name} from ${argument}`);
const npcInstance = new Npc(npc);
return Args.ok(npcInstance);
}

return Args.error({
argument,
parameter,
identifier: "InputNotAnNpc",
message: `\`${parameter}\`was not recognized as an NPC.`,
});
});
export default Args.make<Npc>(async (parameter, { argument }) => {
const npc = await NpcService.getNpc(parameter);

if (npc) {
Logger.trace(`DrpgNpcArg MATCH: ${npc.name} from ${argument}`);
const npcInstance = new Npc(npc);
return Args.ok(npcInstance);
}

return Args.error({
argument,
parameter,
identifier: "InputNotAnNpc",
message: `\`${parameter}\`was not recognized as an NPC.`,
});
});
Favna
Favna15mo ago
No that's the shortest way And using pickResult probably wouldn't really be shorter either Like at most a few lines but it comes with a complexity trade off imho
Bejasc
Bejasc15mo ago
yeah fair enough. Okay, I'll just leave the parameter out of the error message, in the first snippet. I might make a new arg for this case On that note... Is there some way to nest the custom args? Ie could I have Args.make<Npc> as above, but another arg that is Args.Make<Npc | Player> - which tries to sucessfully match against the straight Npc arg? So I can avoid duplicating that code?
Favna
Favna15mo ago
No but you can extract the logic to another function and call that function from both places. Just pass the parameters around as needed For example make the function return a Boolean that you check in the Args.make to know if it's ok or error
Bejasc
Bejasc15mo ago
That's a good point, I'll head down that path. Cheers!
Want results from more Discord servers?
Add your server