Error with the promise/catch from a Firestore query - javascript

I've modified the code below a bit but this is an externally facing endpoint where a mobile client can ping this endpoint and send some pushes to appropriate users.
However, in my console, I'm getting an error:
UnhandledPromiseRejectionWarning: TypeError: assert.isNotOk is not a function
function myFunc(request, response) {
var db = firestore.firestore();
db.collection("myCollection")
.doc(request.params.someParam)
.get()
.then(docSnapshot => {
if (docSnapshot.exists) {
for (var userId of request.params.userIds) {
sendPush(userId, request.params);
continue;
} else {
response.error("Unable to get param");
}
}).catch((error) => {
assert.isNotOk(error, 'Promise error');
done();
});;
});
Any idea what I'm doing wrong here? Thanks

As you can see in the documentation for node's assert, there is no method called isNotOk. However, this is a method called ok. In any event, it's not clear to me what you're trying to do with that line, since you already know at that point that there's an error. Perhaps you just want to log it?

Related

SignalR error when invoking method on the server from JavaScript client

I have a C# server running my hub class, which contains only 1 method in there, which is as follows,
public class HothHub : Hub
{
public async Task AddSingleUserGroup(string name)
{
await Groups.AddToGroupAsync(Context.ConnectionId, name);
}
}
I also have a JavaScript client, which connects to the hub via the following code,
var connection;
async function signalRStart() {
connection = new signalR.HubConnectionBuilder()
.withUrl("https://somesignalrurl.com/hothhub", { withCredentials: false })
.withAutomaticReconnect()
.configureLogging(signalR.LogLevel.Information)
.build();
connection.on("hothHubToHothUpdate", () => {
console.log("Called by the server!");
});
connection.onreconnecting(error => {
console.log("Connection lost due to error " + error + ". Reconnecting.");
});
// Start the connection.
await start();
}
async function start() {
try {
await connection.start();
connection.invoke("addSingleUserGroup", "someUniqueUserName");
} catch (err) {
console.log(err);
setTimeout(start, 5000);
}
};
Now when the client initiates the connections and run start() on itself, this part seems to run fine. A connection to the signalR hub is made successfully. The problem I'm having is when connection.invoke("addSingleUserGroup", "someUniqueUserName"); is run although the error does not happen all the time. On first run, the method at the server end is hit successfully however, it looks like subsequent calls to it fail and this is the error returned in the client,
Uncaught (in promise) Error: Failed to invoke 'addSingleUserGroup' due to an error on the server. HubException: Method does not exist.
at _callbacks.<computed> (signalr.js:1252:36)
at HubConnection._processIncomingData (signalr.js:1364:33)
at HubConnection.connection.onreceive (signalr.js:985:52)
at webSocket.onmessage (signalr.js:2236:30)
I've read a few articles on here but most seemed to be related to the client calling the wrong method name having used a capital letter at the start of the method name when invoking it and some having mentioned issues with the method expecting 1 type parameter and receiving another type although in my instance here its hard to think how the server would not treat the incoming parameter as a string, which is what is being passed in. Has anyone got any ideas on what could be wrong here or what I could try?
Thanks!
Unfortunately I dont have an actual answer for this but after deploying the solution to my Azure App Service, the release version does not produce the error. It seems the error only persisted when in debug mode but like I said I'am not sure why.

Discord.js: (node:147) UnhandledPromiseRejectionWarning: Error: timeout of 1000ms exceeded

So recently for some unknown reason, I started seeing regular errors in the console. Like this:
(node:147) UnhandledPromiseRejectionWarning: Error: timeout of 1000ms exceeded
at createError (/home/runner/ricebot/node_modules/axios/lib/core/createError.js:16:15)
at RedirectableRequest.handleRequestTimeout (/home/runner/ricebot/node_modules/axios/lib/adapters/http.js:280:16)
at RedirectableRequest.emit (events.js:314:20)
at RedirectableRequest.EventEmitter.emit (domain.js:483:12)
at Timeout._onTimeout (/home/runner/ricebot/node_modules/follow-redirects/index.js:166:12)
at listOnTimeout (internal/timers.js:554:17)
at processTimers (internal/timers.js:497:7)
It also sometimes make my bot's latency go to 30000 ms.
I only have Axios parts in my fun commands and here is one of them (however it still works properly, just logs the error):
const url = 'https://no-api-key.com/api/v2/animals/cat';
let image;
let fact;
try {
const { data } = await axios.get(url);
console.log(data);
image = data.image;
fact = data.fact;
} catch (e) {
console.log(e)
return message.channel.send('An error occured, please try again!');
}
This didn't use to be a thing.
Since your axios call doesn't have a catch it is normal to get this error or warning.
It is important to manage axios requests to prevent these kind of issues. Also, I assume, the sample you show is missing some data because you won't need to define result variables outside of the catch state, so I assume you have a loop or something that can cause this as well.
If you are making calls to same endpoint in a loop or with Promise.all, sometimes you need to limit concurrent requests. If it is not the case please ignore this part.
First of all, make sure to set your axios.default.timeout value correctly to define when to cancel the request if there was is response.
Define a response status check your with your requirements.
function checkStatus(response) {
if (response.status >= 200 && response.status < 300) {
return response;
}
const error: any = new Error(response.statusText);
error.response = response;
throw error;
}
Define a parse code to make sure you always have same structure.
function parseJSON(response) {
return response.data;
}
Define a catch functionality to check errors and decide whether to throw errors or just log them.
function catchError(e){
console.error(e);
// TODO send a message
return null;
}
Let's use them in a single call with .catch.
const myResult = await axios.get(url)
.then(checkStatus)
.then(parseJSON)
.catch(catchError);
console.log(myResult);
if I'm not mistaken, you can't access properties from a promise directly, as declaring a variable from a property is synchronous while your url() method is asynchronous.
The data type of axios.get(url) is Promise when the response is not returned so it doesn't have a data property which you are accessing early on. Therefore you have to wait for the response. As when the response is returned the data type of that method changes to what it is intended to be. That's when you can access the data property
So I think your code should be like the following:
const url = 'https://no-api-key.com/api/v2/animals/cat';
let image;
let fact;
try {
const axiosUrl = await axios.get(url);
const data = axiosUrl.data;
console.log(data);
image = data.image;
fact = data.fact;
} catch (e) {
console.log(e)
return message.channel.send('An error occured, please try again!');
}
Assuming that this block of code is in an async context, it should work fine.I hope this answer was of use for you.

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' );
}
}

Returning Error Values Through Axios/Express To React App

I've got a handleSubmit function that fetches data from my backend as part of a larger component. I'd like to send the error information to my redux store and/or local component when the back-end fails, but am unable to do so.
The handleSubmit function looks like this (it's using React hooks, which are wired up correctly. Can post the full component if that is useful):
const handleSubmit = async (e, { dataSource, filter, filterTarget }) => {
e.preventDefault();
setIsLoading(true);
setErrorValue(null);
setError(false);
const token = localStorage.JWT_TOKEN;
const link = filterTarget === "Identifier" ? `http://localhost:8081/api/${dataSource}/${filter}`: `http://localhost:8081/api/${dataSource}?filter=${filter}&filterTarget=${filterTarget}`;
try {
let data = await axios.get(link, { headers: { authorization: token }});
props.setData(data);
setError(false);
setIsLoading(false);
} catch (err){
setErrorValue(err.message);
setError(true);
setIsLoading(false);
};
};
I'm intentionally making bad requests through the form, which will trigger an error in my backend. These are handled through my custom Express middleware function, which looks like this (I'll add more once I get this framework to work):
handleOtherError: (error, req, res, next) => { // Final custom error handler, with no conditions. No need to call next() here.
console.log("This error handler is firing!");
return res.status(500).json({
message: error.message,
type: "ServerError"
});
}
I know that this function is firing because the console.log statement is appearing on my server, and if I change the status code, so does the status code error on the front-end in my Google Chrome console.
In fact, if I go to the network tab, the correct error information appears for my request. Here's the video of me making a bad request:
However, when I try to access the err.message on my front-end, I'm not able to do so. The err.message in my try/catch handler for the handleSubmit function only ever gives me the Request failed with status code XXX
What am I doing wrong?
See https://github.com/axios/axios#handling-errors
You can access the response by using err.response.data.message, not err.message.
Found the answer posted elsewhere: https://github.com/axios/axios/issues/960
Apparently, to get the message, you have to use err.response.data.message
Simply using "err" will only give you a basic string respresentation of the error.

Angular 2 Http get not triggering

As said in the title, nothing is happening when I subscribe to my observable. There is no error in the console or during the build. Here is my code :
My service
getBlueCollars(): Observable<BlueCollar[]> {
return this.http.get(this.defaultAPIURL + 'bluecollar?limit=25').map(
(res: Response) => {
return res.json();
});
}
My component
ngOnInit() {
this.planifRequestService.getBlueCollars().subscribe(
data => {
this.blueCollars = data;
console.log('Inner Blue Collars', this.blueCollars);
},
err => console.log(err)
);
console.log('Value BlueCollars : ', this.blueCollars);
}
So the second console.log is triggering with "Value BlueCollars : Undefined", and the log in my subscribe is never showed. As well, I can't see the request sent in the Networt tab of Chrome.
So I tried to simplify everything with the following code :
let response: any;
this.http.get('myUrl').subscribe(data => response = data);
console.log('TestRep: ', response);
Same problem here, no error, response is undefined. It seems the subscribe is not triggering the observable. (The URL is correct, it is working on my swagger or with postman.)
I'm on Angular 2.4.9
Edit
So I tried to copy/past the code of my request on a brand new project, everything is working fine. The request is triggered and I can get the JSON response correctly. So there is something maybe on the configuration of my project that is forbiding the request to trigger correctly.
Ok just found what was going on. I am using a fake backend in order to try my login connexions that is supposed to catch only specified URL. However for wathever raison it was catching all the requests, so that explain everything. Thx for your help everybody.
Try adding a catch block to your service code:
getBlueCollars(): Observable<BlueCollar[]> {
return this.http.get(this.defaultAPIURL + 'bluecollar?limit=25')
.map(
(res: Response) => {
return res.json();
})
.catch(err => Observable.throw(err))
}
Don't forget to
import 'rxjs/add/observable/throw';
import 'rxjs/add/operator/catch';`
I imagine this will result in the error that'll give you an idea where your code is going wrong.
The reason the console.log outside the subscribe call is undefined is because the subscribe/http call is happening asynchronously and so, in effect, the order (in time!) the code is running is:
1) the observable is subscribed to (and then waits for a response)
2) the outer console log runs with blueCollars undefined
3) when the response (or error) comes back from the http request (potentially after several seconds), only then will the inner assignment of this.blueCollar = data happen (and the inner console log), OR an error will get logged
Apart from that the subscribe code looks fine...!

Categories

Resources