Trying to get Client from ShardingManager for Test Suite

Hello! I'm trying to create a test suite for my Discord Bot. I had a working version without sharding, but once I added sharding to simulate the actual production environment, it kept spawning 2 instances of the bot.
27 Replies
d.js toolkit
d.js toolkit8mo ago
- What's your exact discord.js npm list discord.js and node node -v version? - Not a discord.js issue? Check out #other-js-ts. - Consider reading #how-to-get-help to improve your question! - Explain what exactly your issue is. - Post the full error stack trace, not just the top part! - Show your code! - Issue solved? Press the button! - Marked as resolved by OP
Rocky43007
Rocky43007OP8mo ago
To counteract it, I tried using shard.eval to get the Client instance from ShardClientUtil, but I keep reaching the following error:
Rocky43007
Rocky43007OP8mo ago
Here is a gist with the code and the last working version: https://gist.github.com/Rocky43007/75803ae37f5c3e832bd2d4371f355296
duck
duck8mo ago
just to clarify, the error shown still points to at Client.toJSON, which suggests that a Client is still being flattened, which is what lead me to believe that you hadn't updated every instance of shard.eval() this is why I was asking for the full updated code
Rocky43007
Rocky43007OP8mo ago
Ah, I did update tester.ts with the latest version I tested
duck
duck8mo ago
shard?.eval(c => c.once('ready', async () => {
await runAllTests();

return '';
}));
shard?.eval(c => c.once('ready', async () => {
await runAllTests();

return '';
}));
you're still returning the client here the string is being returned from the event listener callback though as mentioned previously, you still wouldn't have access to runAllTests since this is being evaluated in a different context
Rocky43007
Rocky43007OP8mo ago
Hm.
duck
duck8mo ago
(and as a side note, the Client being returned is also the reason you were receiving your original error on worker mode)
Rocky43007
Rocky43007OP8mo ago
👍 Welp, I tried this and it didn't work because Client is always null:
try {
let client: Client | null = null;

shard?.on('ready', () => {
shard?.eval(c => {
c.on('ready', () => {
client = c;
});
return {};
});
});
if (client === null) {
throw new Error('Client is null');
}
runAllTests(client);
} catch (e) {
console.error(e);
process.exit(exitCode);
}
try {
let client: Client | null = null;

shard?.on('ready', () => {
shard?.eval(c => {
c.on('ready', () => {
client = c;
});
return {};
});
});
if (client === null) {
throw new Error('Client is null');
}
runAllTests(client);
} catch (e) {
console.error(e);
process.exit(exitCode);
}
Gist: https://gist.github.com/Rocky43007/75803ae37f5c3e832bd2d4371f355296#file-tester_v3-ts (At this point, I'm just going to document what it took to get it working [if it ever works] for future devs)
duck
duck8mo ago
I think you may be misunderstanding what I mean by "this is being evaluated in a different context" the eval'd function executes on the client's process/worker it is not executed here in this scope where client is defined as mentioned previously, this method is for sending code to the shard to execute there there is no means of returning the client back to the ShardingManager
Rocky43007
Rocky43007OP8mo ago
Ohhhhh, that makes more sense :faceDesk: So, I've changed gears and I'm trying to have the mock_interaction generated before being sent to a test event on client. I've had it work with c.emit("test," "test") with the bot's client.on("test") outputting test in the console. However, the second I try this:
try {
// let client: Client | null = null;

shard?.on('ready', () => {
const inter = generateMockInteraction('status');
console.log(inter);
shard?.eval(c => {
c.emit('test', inter);
});
});
// if (client === null) {
// throw new Error('Client is null');
// }
// runAllTests(client);
} catch (e) {
console.error(e);
process.exit(exitCode);
}
try {
// let client: Client | null = null;

shard?.on('ready', () => {
const inter = generateMockInteraction('status');
console.log(inter);
shard?.eval(c => {
c.emit('test', inter);
});
});
// if (client === null) {
// throw new Error('Client is null');
// }
// runAllTests(client);
} catch (e) {
console.error(e);
process.exit(exitCode);
}
I now get Error [ReferenceError]: inter is not defined. Now, this should be working because I'm running the code and just sending an object now to the client. But... it's not.
duck
duck8mo ago
this is the same issue
Rocky43007
Rocky43007OP8mo ago
Oh, come on!
duck
duck8mo ago
however for this specifically, you can send the mock interaction as part of the context assuming it's json serializable
d.js docs
d.js docs8mo ago
:guide: Sharding: Additional information - Eval arguments The context option only accepts properties which are JSON-serializable. This means you cannot pass complex data types in the context directly. For example, if you sent a User instance, the function would receive the raw data object. read more
duck
duck8mo ago
(actually <Shard>.eval() seems to take the second param as the context as opposed to a context option in an options object)
Rocky43007
Rocky43007OP8mo ago
So something like
shard?.eval((c, context = inter) => {
c.emit('test', context);
});
shard?.eval((c, context = inter) => {
c.emit('test', context);
});
? Which, doesn't work. But that might be because I just don't understand the docs. Ok, figured it out! Got a better error this time: TypeError: Do not know how to serialize a BigInt
duck
duck8mo ago
well do you have a bigint in your mock interaction? as mentioned previously, the context needs to be json serializable
Rocky43007
Rocky43007OP8mo ago
Maybe it's the bitfields? It was the bitfields Wait, can client emit to the sharding manager?
duck
duck8mo ago
that depends on what you want to emit <Client>.shard.send() exists (though I wouldn't recommend using it unless you know what you're doing), but it's not as if it can send anything that can't be sent through an eval
Rocky43007
Rocky43007OP8mo ago
I just need it to send a string saying testComplete and that's it. Hm. client.shard.send() should work.
duck
duck8mo ago
to be more specific, I believe it emits the message event on the ShardingManager (which it seems that this is no longer documented despite <ShardClientUtil>.send() being documented) but in general this would be leaving the scope of what we support
Rocky43007
Rocky43007OP8mo ago
Fair enough. I did get it working though. Thanks for all your help! Also, JSON serializable can't send functions if I'm correct?
duck
duck8mo ago
correct
Rocky43007
Rocky43007OP8mo ago
Cool
Rocky43007
Rocky43007OP8mo ago
If anyone wants the working code, here it is: https://gist.github.com/Rocky43007/f0c8f75a37c846ffcd21ab9ad4bb8e8b WARNING: You do have to patch any functions used in the Interaction object. For example, .reply() needs to be patched in the interaction object from the client side or your command will error out why it tries to run <CommandInteraction>.reply()
Gist
Discord Bot Automated Command Tester
Discord Bot Automated Command Tester. GitHub Gist: instantly share code, notes, and snippets.
Want results from more Discord servers?
Add your server