NodeJS Package: error handling - javascript

I have some code that uses an Overwatch API to grab some data. This is what I currently have:
OWoverallStats: (playerName, mode, region) => {
mode = (typeof mode === 'undefined') ? 'competitive' : mode.toLowerCase();
region = (typeof region === 'undefined') ? 'us' : region.toLowerCase();
playerName = playerName.replace('#', '-');
return fetch(`https://owapi.net/api/v3/u/${playerName}/stats`)
.then(res => res.json())
.then(data => {
return data[region].stats[mode].overall_stats;
});
}
This works fine, providing you enter a playerName that actually exists. The code I used to test this is:
core.OWoverallStats('Calvin-1337', 'quickplay', 'eu').then(data => {
console.log(data.tier) // grandmaster
}).catch(e => {
console.log(e);
});
In the actual code, I can check if the error code is 404 (player doesn't exist) but then I don't know what I can do with that. I don't want to throw an error, or console log it as if someone implemented this say into a Discord Bot, I'd want the person using the code to say what they wanted to do with the error.

When fetch has a response, if the status is 404 Simply throw an Error. The caller of your code can then catch it and handle however he likes.
For example, your code:
return fetch(`https://owapi.net/api/v3/u/${playerName}/stats`)
.then((res, meta) => {if (meta.status ===404) throw new Error('NoPlayer')})
The caller of your code:
core.OWoverallStats('Calvin-1337', 'quickplay', 'eu').then(data => {
}).catch(e => {
//this is where he can handle the error flexibly
});
You may see other error handling practices here

Related

Javascript .fetch(api) not executing properly for a Python API

I created a python API which returns based on the input one of three outputs:
"Success (email already exists)"
"Success"
"Invalid Email"
I have atatched what the output looks like when called directly from a browser. So the issue is when I call this API in my code, it doesnt execute switching to another page and keeps showing a error message I created if the API returns "Invalid Email". It shows the error message and doesnt execute even if the API returns "Success". I know the API is working and returning the correct outputs as the API is executing the relative commands on some files. How can I fix this? Here is a snippet from my websites code.
form.addEventListener('submit', (event) => {
event.preventDefault();
const formData = new FormData(form);
const name = formData.get('name');
const email = formData.get('email');
const apiURL = `http://censored-for-privacy/?name=${name}&email=${email}`;
fetch(apiURL)
.then(response => response.text())
.then(data => {
if (data === 'Success (email already exists)' || data === 'Success') {
window.location.href = 'main.html';
} else if (data === 'Invalid Email') {
errorMessage.style.display = 'block';
form.reset();
}
})
.catch(error => {
console.error('Error:', error);
errorMessage.style.display = 'block';
form.reset();
});
});
I have tested the API and it works well, I tried changing 'main.html' to a url for google still doesnt work. It executes the alternate function.

NextJS getting param from request.body if it doesnt exist

I have the following code in my nextJS api:
export default async function handler(request, response) {
if (request.method === "POST") {
const type = request.body.type ?? 'body type'
const id = request.body.id ?? 34
console.log(type, id)
if(!type || !id ) {
// Not acceptable. You are missing a required parameter.
return response.status(406).end()
}
const data = await getObjects(type, id)
return response.status(200).json(data);
} else {
return response.status(405).end();
}
}
However, if the API doesnt get one of the parameters (type or id) then it causes an XML error.
XHRPOSThttp://localhost:3002/api/list-objects
[HTTP/1.1 406 Not Acceptable 262ms]
[Fast Refresh] rebuilding hot-dev-client.js:159:24
XML Parsing Error: no element found
Location: http://localhost:3002/api/list-objects
Line Number 1, Column 1:
If the params dont have a value it fails in this same way. How can I ensure it fail gracefully if the values are not present? I would have thought the ?? operator would take care of that but its not fixing the error.
If you use fetch on the client, it doesn’t handle error status codes as errors, so it’s probably trying to parse your error (empty) content.
Before parsing the result, you can check the returned status code and throw an error if it isn’t 200:
fetch('/your/api', {method: 'POST'})
.then(res => {
if (res.status !== 200) {
throw new Error('API returned an error')
}
// Do your parsing here. E.g. for JSON:
return res.json()
})
.then(data => console.log(data))
.catch(err => console.error(err))

Window.open opens new window but server says "URL not found". Is there a way to capture that situation?

I have app that uses Google Books API to grab some informations. Besides grabbing informations it also connects to WEB Page of chosen book. The problem is as follows: there are two subdomains with books. One has(I guess) really all books and the second only some (but the second shows more info!).
const showDetailedInfo = (item, redirect) => {
const id = item[item.length - 1];
console.log(item);
if (id && (typeof id === "string" || id instanceof String)) {
const path = 'https://play.google.com/store/books/details?id=' +id;
try{let newWindow = window.open(path, "_blank");}
catch(err){
let result ={error: true, errorMessage:err.message}
store.dispatch({ type: "RECEIVE_BOOKS", payload: result });
redirect.error();
}
}
};
I would like as follows: if the book is not in second (with more info) subdomain, I will go to page with less info. The problem is that I can not catch that event.
When the book is not in second I receive such the screen:
https://play.google.com/store/books/details?id=aGcBwwEACAAJ
And valid variable newWindow (acc to MDN it should revert null onerror - but it is not error! The page has been opened).
So, my question is whether it is possible to catch such the situation? I have read some on getting external page content and think it is not possible, but maybe there is another solution.
You can use Fetch API to detect if there is any error. Also you can check response.
fetch("https://play.google.com/store/books/details?id=aGcBwwEACAAJ")
.then((response) => {
return response.json();
})
.then((data) => {
console.log(data);
})
.catch((error) => console.log("error", error.name));

Using Discord.js to get all of the messages sent since the bot went offline

So I am making a bot that will store all of the messages sent in a channel into a txt file on my computer. Since I don't have my computer on all the time and I run the bot on my computer it leaves gaps in messages stored in the .txt file. I am trying to make it so that my bot will get all the messages sent since it went offline and store all of them in my file. I created a txt file that saves the message id of every message, it will overwrite the last message so its basically just a file with one message id in it. When my bot starts a boolean variable is instantiated to false and will be set to true once the startup procedure has been completed. This is what I have so far:
var latest;
var beenRunning = false;
bot.on('message', msg => {
latest = msg.id;
if(beenRunning == false) {
msg.channel.messages.fetch(latest, {limit: 100})
.then(messages =>
//code to get messages since last online
)
.catch(console.error);
beenRunning = true;
}
else {
messageTest(msg);
}
fs.writeFile('lastMsg.txt', latest, (err) => {
if (err) throw err;
})
});
I am not sure how to get every message since going offline using the fetch() method. How would I do this?
Not sure how you are structuring your lastMsg.txt, so I just used json.
Might be a bit slow since it'll be a bigger file and its using a lot of array higher functions
let logged = require("./lastMsg.json");
let beenRunning;
bot.on('message', msg => {
if (!beenRunning) {
msg.channel.messages.fetch({ limit: 100 })
.then(messages => {
const reduced = messages
.map(e => ({ id: e.id, content: e.content }))
.filter(e => {
return logged.find(l => l.id === e.id && l.content === e.content);
});
logged = logged.concat(reduced.array());
beenRunning = true;
})
.catch(console.error);
} else {
messageTest(msg);
}
fs.writeFile('lastMsg.json', JSON.stringify(logged), (err) => {
if (err) throw err;
})
});
Initalize your ./lastMsg.json to
[]

Firebase response depending on Firestore Query does not work

Depending on whether there is an entry in Cloud Firestore with the correct DocumentId. However, this does not work because my function sends the status 200 before even finishing the query. So how can I get that working?
Here is my code:
access = false;
admin.firebase().collection("tuere").doc(door).collection("eintritt").get().then((snapshot) => {
snapshot.forEach((doc) => {
if(doc.id === uid){
access = true;
console.log("May open door " + uid);
}
});
}).catch((err) => {
console.log(err);
});
res.status(200).send(access);
When I open the Tab in Chrome and let it load "false" appears, but when I wait like 15 Seconds "May open door (uid)" appears in the Logs.
How can I solve this problem and how can i get my function to run faster?
You should send the HTTP response when the promise resolves, so within the then of the query promise: like that:
access = false;
admin.firebase().collection("tuere").doc(door).collection("eintritt").get()
.then((snapshot) => {
snapshot.forEach((doc) => {
if(doc.id === uid){
access = true;
console.log("May open door " + uid);
}
});
res.status(200).send(access);
}).catch((err) => {
console.log(err);
res.status(500).send(err);
});
Also, you should send an HTTP response in case of error, this is why I added res.status(500).send(err); in the catch
I would suggest you look this video from Doug Stevenson: https://www.youtube.com/watch?v=7IkUgCLr5oA
Also there is a point which surprises me: shouln't you use
admin.firestore().collection("tuere").doc(door)....
instead of
admin.firebase().collection("tuere").doc(door)
I have to look in the reference, but I have the feeling that admin.firebase() does not exist.

Categories

Resources