Reponse Failed in nodejs. How to handle properly - node.js

Cases:
When i insert the data in database through nodejs service. Data Insert successfully in Database(like mysql)
But response failed(for example client call insert service data successfully stored in database. but response failed for network problem anything, client don't know data inserted or not)
So How to handle above case properly?

Your question is bit wide for answer , but still I think , this is might be what you are looking for
model.User.create({your_data})
.then(user => { // if all goes right the this block will be executed
}).catch(err => { // if anything goes wrong this block will be executed
console.log(err);
// from here you can send err in response OR redirect to error page
})

Related

How can I authorize to send a GET request from one GCLOUD function to another

Trying to hit a gcloud function's endpoint via GET to trigger the http function. All I need to do is hit the endpoint with some param values to trigger the function.
We are not allowing unauthenticated on these functions so I need to authenticate in order to send it but cannot for the life of my find a working example on how to do this.
I have read this and quite literally gone in circles following the links in their documentation trying to find what I need to do to set this up.
The function I am hitting sends a message when everything has updated for the day
https.get(`${endPoint}`, (resp) => {
// The whole response has been received. Print out the result.
resp.on('end', () => {
console.log(JSON.parse(data).explanation); // Should return the text set int he function, current, "It's Done"
res.status(200).send(`SQL INSERTs have all been run for client(${clientId}) and they have been notified`);
});
}).on("error", (err) => {
console.log("Error: " + err.message);
res.status(200).send(`There was an error running SQL INSERTs for client(${clientId}) and they have not been notified, error ${err.message}`);
});
In the logs for the function I am trying to hit it returns
The request was not authenticated. Either allow unauthenticated invocations or set the proper Authorization header. Read more at https://cloud.google.com/run/docs/securing/authenticating Additional troubleshooting documentation can be found at: https://cloud.google.com/run/docs/troubleshooting#unauthorized-client
So I am specifically trying to figure out what I need to do, exactly, in order to authenticate and hit the endpoint via a GET request.
Since posting this question I have also created a service account and downloaded the credentials, which is set to GOOGLE_APPLICATION_CREDENTIALS, so if there is a solution using that JSON file I can try that as well.

Dynamically passing dbName to mongoose.connect

For a MEAN app, I need to pass the dbName depending on the logged-in user. The flow of events is as follows.
User logs-in and gets authenticated using an auth specific REST-API.
Auth-API returns to Angular the user account data which includes the userSpecificDbName.
Thereafter, Angular makes all calls to the app's main REST-API. With all calls to the API, account data is passed and the API shd use the dbName from the account data in the following statement of app.js
mongoose.connect(uri, { dbName: <userSpecificDbName> })
.then( () => {
console.log('Connection to the Atlas Cluster is successful!')
})
.catch( (err) => console.error(err));
Is this possible? And how do I pass data in app.js for this purpose?
It is certainly possible to do that, Although keep in mind you would need to open and close connections per request to do that, which is not a regular pattern in Node.js
Normally you would connect to the database once and then fire queries. But in your case, you would disconnect every time after you've sent a response and reconnect and the beginning to the DB.
Alternatively, you could most probably do a useDb call as suggested in the following answer:
switching database with mongoose
That would help you switch the database.

Services should throw exceptions? (Web API)

I found similar questions but not found any good answer so I am posting it again and with more specific environment.
I am using Node.js + Express to build REST APi for my React Native app.
I am using pattern Router->Controller->Service->Database and I am not sure if I am supposed to throw specific errors from my services.
Example:
I am validating registration request.
Field validations are hapenning inside Controller (I am using ajv JSON schema validator).
Now I need to validate if user/email already exists
Am I supposed to do this from controller by calling for example service.emailExists(data.email) before calling service.createUser(data)??
Or I can let database fall on CREATE duplicate, return false from service.createUser(data) and inform user from controller that Email exists. If I do so, I am not able to inform user if there is Unspecified error inside service, because it will always return as Email exists error, even something else happens.
You can use try...catch, or if...else to handle the possibilities of errors.
This is how it worked for me. Service using express and sequelize
const { Keluhan } = require('../../models');
var getAllKeluhan = () => {
return Keluhan.findAll()
.then(data => {
if (data) {
return {
code: 200,
message: "Data Found!",
result: data
};
} else {
return {
code: 404,
message: "Data not Found!"
}
}
})
.catch(err => {
throw err;
})
}
module.exports = getAllKeluhan;
This kind of typical problem can be solved in different ways. i provide below few.
A general way of handling it to fail in Database layer and there will be a cascading of failure from database layer to service layer and then controller layer. In this case it is assumed that there is no graceful failure and in this case, people just broadcast a generic failure. All the errors and exceptions are reported in a log.
The another approach is to make a failure at the service layer itself if the email id already exists in the cache without connecting to database. It seems to be a good approach as long as there is a good synchronization between database and the cache layer.
Another approach would be a proactive failure where once the user enters the email id and makes a tab out in UI, you can connect to database to validate through a service.
Sometimes, it is also thought that let the user enters everything in the UI screen and let us validate at the end.
As far as design is concerned, I think approach should be given by the functional team who propose the idea. Technically, all the approaches are possible.
The most important thing here is to grab the error or exception in the controller and propagate as a bad request. It means user should be notified whether email id already exists or not.
Finally, you can think of the design like Fail-Safe or Fail-Fast as per your requirements.

catch never outputs the console even though I know it's failing

I have my mongodb service stopped, so I know that my front end is not connected to my DB. I am using react and express.
Upon my app starting, I want to indicate that to the user somehow the server is offline so I figured if my original get call for users fails, then the server is offline.
I'm doing a simple call:
componentDidMount () {
axios.get ('/api/users')
.then ((res) => this.setState(
{ users : res.data }
))
.catch ((error) => {
//console.error(error);
console.log('error found : offline');
});
}
But nothing happens in situation. I never get the catch call for the console. Am I going about this wrong? I'm new to backend so this is all a learning experience for me.
I was going to set a failed flag and then render a display error for the user and then retry the connection every 1500ms or something (is that bad programming?).

Node JS & Socket.io Advice - Is it better to post information to a database through a route, or through the socket?

I am currently building a new application which, at a basic level, lets users add a task which needs to be completed, and then lets a different group of users pick up the task and complete it.
Previously, I took over building a real-time chat application written with NodeJS and Socket.io and on that, all the messages were posted to a database over the socket connection.
In the current application I am doing the same, but was thinking if it might be better off to post the information to the database via the route instead, then emitting the socket event on success to update the list of available tasks.
I was just looking for advice, how would you guys do this? Commit info to the database through a route or over the socket?
If you go the route way things are pretty much laid out for you to be sure whether or not your update worked or not. Socket doesn't guarantee neither success nor failure, by default.
But you could program to make it. For e.g.
client: send data
socket.emit('update', data); // send data
server: receive data & send back an update as to whether the operation was successful or not
socket.on('update', function(data){
findOrUpdateOrWhateverAsync(function(err){
if(!err) socket.emit('update', null); // send back a "null" on success
else socket.emit('update', err.message); // or send back error message
});
});
client: receive update on error/success
socket.on('update', function(err){
if(err) alert(err);
});

Resources