Node.js: Should I discard request on error? - node.js

When I build server using Node.js. Requests can sometimes fail. For example, there can be error in parsing POST data. When any error happens:
should I continue handling the request and risk that some of those POST data may be corrupt or missing and respond as if nothing happened (or respond and notify the user, that some error happened)?
try to reparse POST data (and if it fails for, let's say, 3 times, stop trying, add error to error log and show error page to user)?
stop the request handling immediately and throw 500 error?
What is the best way?

The key questions to ask yourself in this situation are IMO:
do I know why the error happened;
can I recover from it?
The answers depend solely on your application. Generally, retrying something only makes sense if you can expect a different outcome with the next attempt. This typically applies to various unexpected errors when integrating with external systems. On the other hand, if the error that you get clearly states that it received e.g. a bad request, or that a file does not exist, then this is probably not going to change no matter how many times you retry the same operation.
If your business rules allow you to continue the operation while ignoring the error entirely, then do so. If your business rules allow you to carry out the request partially and you're able to report the partial failure - then do so. If the error prevents any processing of the request whatsoever, then you'll have to terminate it and report back to the user.
It seems to me that you had a particular situation in mind, so let me address request body re-parsing. In a proper system doing this should be utterly pointless - if you expect different outcomes, then there is something fundamentally wrong with your setup because the body of a request should not change once it's received. Your application should never modify request data in any way.
As a more general rule - if you expect that something unexpected might happen in your application, but you have no idea when, why or how, then there is something wrong with how the application is structured / executed. You should own your code and know exactly what it does.

Related

NodeJS - Is it OK to call db insert/update functions without await?

I have a backend application and there are insert/update endpoints. They mostly go as:
Check and validate the input
Submit the input to db
Return status 200/201 with location header set and body contains status message
Would it be ok to make the 2nd step without await so that response can be returned faster? The returned status will be set to 202, which means it is currently processing. The possibility of 2nd step to throw error is extremely low, or if it does there is a bug going on somewhere and does not relate to the end-user anyways, hence no need to return such error to user.
Would this work? Even if this works, would it be a good practice?
It's OK to not wait for the database response to succeed before doing other things (like sending back a response) if that's how you want your app to work and you're sure that's the right design and you've thought through what happens (from the end user's point of view) if that database call (that you didn't wait for) fails.
BUT, it's not OK to ignore a rejected promise that might come back from the database call because unhandled promise rejections should not happen in a nodejs server. So, if you're not going to use an await, then you probably need a .catch() to catch and at least log the error.
Would this work?
Yes. There's nothing in the language or in nodejs stopping your from sending a response before the database call has completed. It's more about whether that's the appropriate way to design your response handler.
Even if this works, would it be a good practice?
It's not a widely recommended practice because the usual sequence is this:
Check and validate the input
Submit the input to db
If success, return status 200/201 with location header set and body contains status message
If error, return appropriate error status (based on type of error) and status message.
I'm not saying that you can never deviate from this sequence, but doing so would generally be the exception, not the rule.
Keep in mind that data validation does not necessarily catch everything that might cause the database to generate an error. For example, you could be creating a new user on your site and the email address is perfect valid in validation, but then the database rejects it because it's not unique (there's already a user with that email address).
And, the database itself could be having problems, causing an error and the user should be informed that the transaction they were trying to submit to the database did not happen event though the error was not directly caused by the user.

Is ending responses in Express with a status code always necessary or recommended?

I'm confused about this. I have seen a lot of people ending responses with just res.send();. At the same time, some tend to include a status code, like res.status(422).send();. I understand that this is useful when a user, for example, has sent a request to /log-in/ with data that represents a type different from the one needed and appropriate. In such cases, I'm ending my responses with res.status(422).send();. If I'm expecting a username, but I instead receive an array, it seems to me that such an approach is appropriate. However, if everything is technically alright and the user has just entered a username that does not exist, do I need to include a status code? When such a thing happens, a message under the form will be displayed instead. And res.send("This username does not exist."); is the function I would call. Should I call res.status(401).send("This username does not exist."); instead?
Technically you are not forced to use status codes however it's recommended to follow the best practices.
When the user does not exist return 404 not 401. 401 is unauthorized
When user input is not expected, that's validation error(bad request) and return 400 instead of 422. 422 is used in slightly different scenarios.
Read more about it 400 vs 422
More details about http status codes
Yes, status codes are very important as a good practice I would prefer 404 instead of 401 in your case res.status(404).send("This username does not exist.");
stackOverflowAnswer
Why do we use the status code?
To make your debug life easy/ better error handling and to log the error in production to know the severity of the error your application has in case it crashes.
How to Specify statusCode in Node.js
When to use what status code
By default, Express answer all endpoints with 200 unless you didn't specified an endpoint, in this case it will automatically reply with 404.
by the way, Express also has res.sendStatus() function that ends the request and sending status
This has to do with your api design. Generally you would be publishing your api specs (Api specification) and there would mention how your client can find out if something is going wrong or going fine.
HTTP Response code are some of easiest way to inform client about outcome of request. So they don't have to go inside the payload of response to check what was outcome. Since most of codes are well know and there is consensus you will write more standard code which works with network elements like proxies, load-balancer etc and understandable developers.
Advantages of status codes

Where are HTTP Status Codes first available in the IIS Pipeline ?

Does anyone have any information on where the HTTP Status Codes (200, 404, 500, etc) are first available in the IIS Pipeline? I'm trying to write a series of http modules and handlers for error handling purposes and I don't particularly want to duplicate requests/responses to get the values.
Take a look at any of the events here, and take your pick :)
http://msdn.microsoft.com/en-us/library/ms693685(v=vs.90).aspx
Theoretically, the status code can be changed by any of the http modules in the pipeline; it just depends on which events they are subscribed to.
For example, an authorization module may subscribe to the OnAuthorizeRequest method, and perform its logic at that time, and change the status code if needed. In another case, a classic ASP app may run as a handler, and you won't be able to determine if the status code is 500 until OnPostExecuteRequestHandler. Finally, an error in a logging module may generate a 500, which doesn't occur until the request processing is nearly finished (OnLogRequest)
Further complicating matters, some handlers may spit out unbuffered data during execution, so it could be in any of the OnSendResponse events, which don't come in any particular order, and the status code could have changed between responses.
So, it really depends on what you're trying to achieve in order to approach this effectively. If you could provide more detail, perhaps we could formulate a solution.

I need to validate and send feedback to a participating server. How can we add Netty request code channel.write() within handler code?

I am coding for a Netty based Notifying Server, which takes in Message Buffer many hundreds at a second from a Server(A) through RPC, and then sends it to an Http Real Time Server, after checking for the validity(the validation consists of checking for a tag ID and its value). If the validation is not successful, the System needs to send an error feedback back to the Server(A) with an Error Code.
I intend to write the validation logic inside a handler, but how do we make the handler to send the feedback if message is found to be invalid?
Can we include database code also into a handler, so I can persist the validation specific details to a Database? Will adding this DB code handicap the Netty performance? If Yes, what's the better way of using a Database (insert) code inside a handler?
Please can anyone guide me? Can I write the DB code inside an Executor?
Kindly excuse me if I am asking a too basic questions. I am still on Learning phase.
Let me try to answer the questions.
1) I think it does not not matter if you want to send an ERROR or SUCCESS response. Just use Channel.write(..) to write it and have an encoder that can handle the encoding to a ChannelBuffer. There is not difference here
2) You should add an ExecutionHandler in front to make sure your db calls do not block the IO-Thread. See [1].
[1] http://netty.io/docs/stable/api/org/jboss/netty/handler/execution/ExecutionHandler.html

Track IIS Internal Error

I use JavaScript to post an Asynchronous Request to a Web Service. This works about 95% of the time. Sometimes, the request fails to be processed.
Below is the error message in the Trace file of IIS:
2009-02-24 06:14:40 W3SVC861612620
10.248.24.20 POST /TestWebService /TestWebService.asmx - 3112 -
10.250.201.45 Mozilla/4.0+ (compatible;+MSIE+6.0;+MS+Web+Services+Client+Protocol+1.1.4322.2032)
500 0 0 1148 954 124876
This shows that the internal Error 500 has occurred to the request. Is there any way that I can get to know this in the JavaScript where i have posted the request from? Any workarounds are also fine.
Since you don't provide information about your javascript library, this will be hard to troubleshoot. However, if you're running on IIS 7, you can enable Failed Request Tracing.
Troubleshooting the old school way: your web method is generating an error 5% of the time, meaning it works in certain cases but fails in others. This is likely caused by the parameters sent to your web method. Even if you're unable to trap any runtime requests to your webmethod, you can inspect your logic to see what parameter conditions would cause a failure. Better yet, build a battery of unit tests to call your web method, passing every possible combination of parameters that is feasible.

Resources