How to write logs in node js - node.js

Recently i got a work to write log messages to my node js project.I am not sure about what exactly a log message mean,generally for a function we write 2 cases like below
exports.inserttopic = function (req, res) {
var topics = new Topics(req.body);console.log(topics)
topics.save(function (err, result) {
if (err) {
console.log(err);
return err;
}
if (result) {
data = { status: true, error_code: 0, result: result, message: 'Inserted successfully' };
}
res.json(data);
});
};
From the above code,i put console.log(err) for error case .is this a log message?If not how does log message s different from it?I heared something that log messages should be ride into a file.How can i do it,i surfed in google but i didnt come to end in understanding.I really troubled about it.Can anyone suggest me some help and post some good articles.Thanks.

A "log message" is only some Text Information which is offered by a program.
The message can be written to different output channels.
E.g. you are using the Console channel which is bound on the running program. This means when the program ends the log message may get lost if you don't save it explicitly (e.g. with a text-editor in a file).
The better way is to log into a so called "log-file".
You can write your own function which writes to a file or you can use some logging-framework.
The benefit on a logging framework is, that it mostly offers you the ability to choose, which output channel you prefer (for example also Database!), how the logging message has to look like (e.g. Date and Time at the beginning of each line) and that it offers you different severities.
Severities can be for example of type:
Error
Info
Debug
The Logging Framework (or your configuration) then decides how to handle the different severities.
Write the severities in different Logfiles (debug.log, error.log)
Write only messages over the configured Severity Level (e.g. Level Info skips debug messages)
...

Related

Keep track of specific errors in Google Cloud Error Logs?

I am using GCP with Cloud Run, SQL etc with a Node.js application. I have a specific type of error that appear quite often, related to a Twitter API call. Quite often I get this "Rate limit exceeded" error from the API which I handle like this:
items.forEach((item) => {
if (item.body.status == 429) {
throw Error("Rate limit exceeded")
}
}).catch((error) => console.log(error))
This appears in the logs but I would like it to be tracked in GCP Error list https://console.cloud.google.com/errors so I can see if my efforts to limit this specific error is going better. I don't want it to break the script so I also want to catch the error. How can I solve this best?
I haven't been able to reproduce with your exact syntax (I'm not a nodejs expert) but I've been able to get errors reported in both Error Reporting and Logging via the following code:
try {
items.forEach((item) => {
if (item.body.status == 429) {
console.log(new Error("Rate limit exceeded"));
}
})
}
catch (error) {
console.log(error);
}
Note that instead of throwing the error in the if block I just console.log(new Error("Rate limit exceeded")) and Error Reporting automatically picks it up.
The "Rate limit exceeded" does appear for me out of the box in the Error Reporting dashboard:
and in the logs:
Also note that the Logging page has an histogram view above the log entries that shows occurrences of the logs over time. By just filtering on the textPayload with the errors, you can view a detailed count of these errors over time in the histogram.

How to decide between RPC and REST for APIs?

I have made an application where the user will send the Program in either C or Python and Input via STDIN, and my API will return back the output of Program in JSON Format.
Nodejs/Expressjs Code :
route.post('/exec', (req, res, next) => {
if(req.body.lang === 'c')
cExec(req, res)
if(req.body.lang === 'py3')
py3Exec(req, res)
})
And after the code execution in py3Exec() and cExec(), I wrote this to send back the output, using Exit Codes:
if(code === 0)
{
if(stdout === req.body.output)
res.send({
"result": "AC",
"output": stdout
})
else
res.send({
"result": "WA",
"output": stdout
})
}
else
{
res.send({
"result": "ERR",
"error": stderr
})
}
https://github.com/vkartik97/Online-IDE-API/blob/master/routes/run.js#L41
So, this API is REST. I wanted to know if this is Perfect way for this Use Case or if RPC should have been used as REST is used only for Resources from Server whereas RPC is used for Function Invocation(which is my case, maybe).
Thanks!
In my opinion it's not really a big deal which way you go, a lot will depend on the rest of the application. If all your application does is consume code, run it, and provides an output then either would most likely be fine.
You obviously can see how this might be an RPC call, with something like /exec, but it could also easily be a REST call, especially if you wanted to add some form of logging. For example: POST /program could be designed to consume some code, create a "program" in a database, run the code, and log the output along side the program in the database. You'd then return the program and it's response to the client.
If you're literally just consume code, running it, and giving an output back across HTTP then I'd be tempted to go with a JSON-RPC sort of endpoint for simplicity and to reveal intent (simply triggering an action).
Much depends on the future of your application and how much bigger it might become, and what other functionality you will have. If you're going to have a 90% RESTful API and a couple endpoints as a JSON-RPC, then I'd just go with a REST API for everything for consistency.

What is considered standard when dealing with database errors in a REST application?

I'm currently writing a public REST service in Node.js that interfaces with a Postgres-database (using Sequelize) and a Redis cache instance.
I'm now looking into error handling and how to send informative and verbose error messages if something would happen with a request.
It struck me that I'm not quite sure how to handle internal server errors. What would be the appropriate way of dealing with this? Consider the following scenario:
I'm sending a post-request to an endpoint which in turn inserts the content to the database. However, something went wrong during this process (validation, connection issue, whatever). An error is thrown by the Sequelize-driver and I catch it.
I would argue that it is quite sensitive information (even if I remove the stack trace) and I'm not comfortable with exposing references of internal concepts (table-names, functions, etc.) to the client. I'd like to have a custom error for these scenarios that briefly describes the problem without giving away too detailed information.
Is the only way to approach this by mapping every "possible" error in the Sequelize-driver to a generic one and send that back to the client? Or how would you approach this?
Thanks in advance.
Errors are always caused by something. You should identify and intercept these causes before doing your database operation. Only cases that you think you've prepared for should reach the database operation.
If an unexpected error occurs, you should not send an informative error message for security reasons. Just send a generic error for unexpected cases.
Your code will look somewhat like this:
async databaseInsert(req, res) {
try {
if (typeof req.body.name !== 'string') {
res.status(400).send('Required field "name" was missing or malformed.')
return
}
if (problemCase2) {
res.status(400).send('Error message 2')
return
}
...
result = await ... // database operation
res.status(200).send(result)
} catch (e) {
res.status(500).send(debugging ? e : 'Unexpected error')
}
}

Socket.io error passing conventions

Background: In Node, it is common to pass an error object to a callback function in async calls as well explained in Error handling in Node.js by Joyent. A standard error object contains a name, a message, a stack trace and possible additional properties. Passing or throwing strings or plain objects as errors is considered a bad practice. With Socket.io, data can be transmitted from client to server and vice versa by emitting events and having an optional response callback. This opens up multiple ways to pass and handle errors.
Question: If a socket.io event from a client causes an error on the server, what is the best practice to inform the client about this? A plain error object in response? A separate error event and listener? How the error should be structured? Is there any best practices like is the case with Node? What are you using?
Example: Imagine socket.io used for login. A client logs in by emitting a username and a password like below:
socket.emit('login', {user: 'Foo', pass: 'Bar'}, function (response) {
...
});
On a successful login, the response contains a session token. But what if the username or the password do not match? Several approaches come to mind:
Approach 1 - plain error object: The response could contain a property error having a plain error-like object as its value, with standard name and message properties and possible additional ones:
{
error: {
name: 'InvalidUsernameOrPasswordError',
message: 'Username or password was invalid.',
usernameExists: false
}
}
The client thus tests if response contains an error and if not, continues with the login procedure:
socket.emit('login', {user: 'Foo', pass: 'Bar'}, function (response) {
if (response.hasOwnProperty('error')) {
// handle error
}
// do something with response.token
});
Approach 2 - simple string: Similar to Approach 1, but the error property is just a plain string representing the name of the error.
{
error: 'InvalidUsernameOrPasswordError'
}
This approach is light and sufficient in this naïve example but lacks ability to pass additional data about the error.
Approach 3 - separate event: The server could emit and the client listen additional events to handle possible outcomes:
socket.on('loginError', function (error) {
// handle error based on error.name and error.message
});
socket.on('loginSuccess', function (data) {
// handle successful login with data.token
});
socket.emit('login', {user: 'Foo', pass: 'Bar'});
This approach feels the most explicit and pure under the event emitting paradigm but requires multiple event handlers.
Conclusions: There seem to be many possible ways to pass and handle errors. Any experiences, thoughts or feels?
It depends on your "clients". If you have end users like people using an application they really don't care so much about how you send the error. At the end you are going to have a text on the frontend saying they are wrong. So you are the one who have to select which way you prefer for implementing the error handling on the backend.
If your clients are not end users like the case above, imaging you are creating an application or library and you have to say there was an error. You should return as much as information you can in order for people who use your application identify where you error is.
So at the end:
-For customers: You will show your errors on the frontend so that ups to you how you want manage the error.
-For developers: You should show as many error information as you can. Showing the stack trace, error code...

node.js File upload configurations

No Matter how much I've searched and changed and toyed over the last 24 hours, I simply can not find the right combination of settings that allows Node.js to upload multiple files.
My setup is quite simple - I have a form interface that posts multipart content (files) to an endpoint.. lets call it: /theendpoint
and this end point is supposed to parse the multiple files. However, during the parsing, there are various events that need to be called once the file is uploaded.
I'm currently using the express.bodyParser({ uploadDir:'/tmp', keepextensions:true, defer:true}); in the app configuration.
Using the following method, I am trying to parse the file, but the problem is
Only 2 files will begin uploading, and will not complete (ie. the progress bar hangs near the end without fully completing).
The other files to be uploaded by the form (item 3+) do not even begin to upload to the server.
It seems to be some sort of asynchronus holdup, however I can't properly interpret the problem. Some of the code used at the upload endpoint are as follows:
// This applies to /theendpoint route. Using Express.
exports.theendpoint = function(req,res){
console.log(req.files);
fs.readfile(uploadPath, function(err,data){
if(err) throw err;
fs.writeFile(newFilePath, data, function(err){
// Series of checks and definitions
// Database connection
// Conditional executions
fs.unlink(req.files.file.path, function(err){
if(err) throw err;
console.log('Deleted');
});
});
});
};
Obviously I've left out some of the code here. If anyone can help - is this structure workable?
You should know that items in the commented section.. ie DB connection etc. are asynchronus tasks.
after
fs.unlink(req.files.file.path, function(err){
if(err) throw err;
console.log('Deleted');
});
add
res.redirect("back");
and it works!

Resources