Discord.js Throw exception in .catch - javascript

Because the discord doesn't support to delete messages older than 14 days. I want to create an exception to the error, when the bot is trying to delete old messages,but the throw in .catch doesn't work and i don't know why.
This is my code:
try{
message.channel.bulkDelete(200, false)
.catch(error =>{
throw 1;
});
message.channel.send(“Deleted 200 messages”);
}catch(error){
message.channel.send(“cant delete messages”);
}
I know that i can do this bulkDelete(200, true) but that wont throw exception when it is trying to delete the old messages.

Try to do this
try {
await message.channel.bulkDelete(100, false);
message.channel.send("Deleted 100 messages");
} catch(error) {
message.channel.send("Can't delete messages");
}
bulkDelete is a promise so you have to put it in an async function and await it or use the .then syntax. Also it can delete only 100 messages and returns an error with more.
I'm not sure why you want to throw 1 when you get an error but if you need it you can put it in the catch statement after sending the message

Related

asyncronous try catch phrase not working discord.js

I am trying to implement a discord chatbot into my own bot, isn't good at handling some characters and stuff like the quotes of discord (type > and space to know that I mean). It often crashes becauses it thinks the message is empty. I wanted to use a try catch phrase so it won't crash. The complete function is asyncronous and I think that's why it isn't working how I want it to do. It still crashes without logging the thrown error.
client.on("message", async message => {
if(message.channel.id === "1006483461747527772" && !message.author.bot){
if(containsLetters(message.content)) {
//console.log(message.content.length)
try{
let reply = await chat.chat(message.content)
client.channels.cache.get("1006483461747527772").send(reply)
} catch(err){
client.channels.cache.get("1006483461747527772").send(err)
}
}
}
})
#Robotgozoooom's answer is correct that to send an error message to Discord you need to use error.message, but there's another problem: when Discord throws the Cannot send empty message error it is in an async function, so the try/catch doesn't actually catch the error. You need to add a .catch() function to the end of your async function instead of using a try/catch at all:
if (containsLetters(message.content)) {
let reply = await chat.chat(message.content);
let channel = client.channels.cache.get("1006483461747527772");
channel.send(reply).catch((err) => channel.send(err.message));
}
I think the problem that you are running into here is that the object err is not a String. Try appending .message to err so then it reads err.message. If that doesn't work (or even if it does), I would recommend against sending the error message in discord since that presents more variables to interfere with debugging (what if something was wrong with the client object or with the channel id string?). Instead, I normally use console.error(err). Hope this helps!

Execute promises when all resolved (as DB Transactions)

I have two promises that need to act as Transactions, if one of them fails, a "rollback" should occur.
For example: When I create a user I want to send a confirmation email, but what happens if there is an error on sending the email, the user will be created but will never get a confirmation.
await saveUser(user)
await sendEmail(user)
If I switch the order, what happens when something goes wrong on creating the user? It will get a confirmation.
await sendEmail(user)
await saveUser(user)
I thought a Promise.all will do the trick, but it doesn't.
await Promise.all([saveUser(user), sendEmail(user)]);
Is there a way to execute promises as transactions on Javascript? Promises should execute if and only if both of them resolve.
There is no built in 'transaction mechanism' in JavaScript like there is in some databases. You cannot go back in time to undo operations which you have already performed. If you wish to reverse the effects of saveUser when sendEmail fails, then you need to create another function, such as unsaveUser, and invoke it if sendEmail fails.
This can be done in the following way:
Using Promises:
saveUser(user)
.then(() => sendEmail(user))
.catch(err => {
if (err.message === "Email Error") { // Check the exception to determine if the email failed
unsaveUser(user);
}
});
// This will only send the email if 'saveUser' was successful, and call 'unsaveUser' if email fails
Same thing using Async/Await:
try {
await saveUser(user);
sendEmail(user);
} catch(err) {
if (err.message === "Email Error") { // Check the exception to determine if the email failed
unsaveUser(user);
}
}
For this example to work, in your async sendEmail function, you must throw new Error("Email Error"); upon detecting an error. If you are using resolve/reject, it would be reject(new Error("Email Error"));.
I hope this is clear to you and helps you resolve your issue.

Async await only output error message in catch

I have the following async function:
async function register() {
try {
if (password1 !== password2) {
throw "Passwords do not match!";
}
await firebase.auth().createUserWithEmailAndPassword(email, password1)
}
} catch (err) {
document.querySelector("#message").innerHTML = err;
return;
}
The first password match checks if the password entered by the user two times are identical. If they are, then use Firebase to create an account. But Firebase's createUserWithEmailAndPassword function return an error object that contains a error.code and a error.message. I only want to display the error.message and disregard the error.code. Is it possible to do it with the common catch block following the try, or I have to write a specific catch block for createUserWithEmailAndPassword to disregard the error code?
You can try to match the structure of firebase in your
Throw error condition using
throw { message: 'Passwords do not match!' };
And then always deal with the error as an object
In both cases
Edit:
Thanks to Bergi, you can also use this approach which is even better
throw new Error('Passwords do not match!);
Which will also create an object with a message attribute

node express try catch not working as expected

I'm a beginner in Node/Express.js and I'm trying out some try catch logic but doesn't seem to work as expected.
app.get("/tasks/:id", async (req, res) => {
try {
const _id = req.params.id;
const task = await Task.findById(_id);
if (!task) {
return res.status(404).send("task not found");
}
res.send(task);
} catch (error) {
res.status(500).send("Internal server error");
}
});
from this code sample, I'm making a query to Mongo DB to fetch some task but the problem is that if the task is not found, instead of running through the if statement, the program jumps directly to the catch block hence the if condition is not checked thus resulting to a different error. How can I fix this issue?
This is simply how MongooseJS works - check their Promises documentation and you will see that if a document is not found, an error will be thrown. If you were not using await, the findById() documentation shows how an error is returned if it cannot be found:
// find adventure by id and execute
Adventure.findById(id, function (err, adventure) {});
You can simply modify your route to look like the following:
app.get("/tasks/:id", async (req, res) => {
let task;
try {
task = await Task.findById(req.params.id);
} catch (error) {
return res.status(404).send("task not found");
}
/* perform other checks or actions here if desired */
res.send(task);
});
This is a little more flexible if you want to perform other error-checking; task is declared first so it can be accessible outside the try/catch block, and a 404 error is thrown if the task does not exist.
You can also look at the exists method which will return true or false based on if the document exists, but since you need the actual result that does not make as much sense.
You don't indicate what Task is, but it appears that it is rejecting when it doesn't find anything, rather than returning a false value (which is what you seem to be expecting).
Given that, you should probably just handle the error that it is throwing with something like
} catch ( error ) {
// Will need to adapt this if to something that identifies the error thrown by `getById`
if ( error.message.includes( 'not found' ) ) {
res.status( 404 ).send( 'task not found' );
} else {
res.status( 500 ).send( 'Internal server error' );
}
}

Flow control with async without throwing Errors

I am having an issue where Intellij is warning me about 'throw' of exception caught locally. After doing some digging on why this is not ok it makes sense, errors should not be used for flow control. The problem I am facing though is in async I cannot reject the promise without throw something locally and I get the warning.
Some of my example code.
Top level takes in the request and awaits for the response from the controller:
Router.post("/", async (req, res) => {
try {
let itemController = new ItemController(req.body);
let response = await itemController.request();
res.send(response);
} catch (error) {
res.status(500).send({ error: error});
}
});
The controller takes in the request and awaits on other functions to get some data.
async request() {
try {
await isValidItem();
return await this.initialize();
} catch(error) {
throw error;
}
}
Then I have a function which gets manufacturer ID for this item and I run into my problem. If the SQL query doesn't fail and nothing is in the response I need to throw a local error so that the request can fail gracefully. and send a proper 500 error to the client.
async queryManufacturerID() {
try {
let result = await this.queryManufacturerID(this.itemID, this.brand);
if (result === false) {
throw new Error("this item has no manufacturer ID");
} else {
this.manufacturerID = result["manufacturerItemID"];
}
} catch (error) {
throw error;
}
}
My problem is I know I can adjust this so other functions that get a reply from this can know that this function failed without a error but that would have to happen in this entire chain to prevent throwing locally. Seems like a lot of bloat.
The only thing that makes this code bloaty and the IDE complain is not throwing errors, but this:
try {
//...
} catch (error) {
throw error;
}
It's a no op. You can safely remove it without changing the logic.
The only case where you should use catch is when you actually plan to handle the error and get the execution back on track.
After doing some digging on why this is not ok it makes sense, errors should not be used for flow control
I disagree. Errors are a part of proper flow control, they allow you to handle unplanned things. Throwing an error if something unexpected occured makes sense, also in this case.

Categories

Resources