Prevent Express.js from crashing - javascript

I'm quite new to Express.js and one of the things that surprised me more at first, compare to other servers such as Apache or IIS, is that Express.js server crashes every time it encounters an uncatched exception or some error turning down the site and making it accessible for users. A terrible thing!
For example, my application is crashing with a Javascript error because a variable is not defined due to a name change in the database table.
TypeError: Cannot call method 'replace' of undefined
This is not such a good example, because I should solve it before moving the site to production, but sometimes similar errors can take part which shouldn't be causing a server crash.
I would expect to see an error page or just an error in that specific page, but turning down the whole server for these kind of things sounds terrifying.
Express error handlers doesn't seem to be enough for this purposes.
I've been reading about how to solve this kind of things in Node.js by using domains, but I found nothing specifically for Express.js.
Another option I found, which doesn't seem to be recommended in all cases, is using tools to keep running a process forever, so after a crash, it would restart itself. Tools like Forever, Upstart or Monit.
How do you guys deal with this kind of problems in Express.js?

The main difference between Apache and nodejs in general is that Apache forks a process per request while nodejs is single threaded, hence if an error occurs in Apache then the process handling that request will crash while the others will continue to work, in nodejs instead the only thread goes down.
In my projects I use monit to check memory/cpu (if nodejs takes to much resources of my vps then monit will restart nodejs) and daemontools to be sure nodejs is always up and running.

I would recommend using Domains along with clusters. There is example in doc itself at http://nodejs.org/api/domain.html. There are also some modules for expressjs https://www.npmjs.org/package/express-domain-middleware.
So when such errors occur use of domain along with cluster will help us separate context of where error occur and will effect only single worker in cluster, we should be logging them and disconnect that worker in cluster and refork it. We can then read logs to fix such errors that need to be fixed in code.

I was facing the same issue and I fixed using try/cache like this. So I created different route files and included each route files in try/cache block like this.
try{
app.use('/api', require('./routes/user'))
}
catch(e)
{
console.log(e);
}
try{
app.use('/api', require('./routes/customer'))
}
catch(e)
{
console.log(e);
}

Related

Apollo Explorer Failed to load resource: net::ERR_CERT_AUTHORITY_INVALID

I am running an Apollo Server with express to create an http server:
const express = require("express");
const cors = require('cors');
const app = express();
const server = new ApolloServer({ ... });
server.applyMiddleware({ app });
// enable pre-flight for cors requests
app.options('*', cors());
// Create the HTTP server
let httpServer = http.createServer(app);
httpServer.listen({ port: config.port });
Locally I can run the server and query it on Apollo Explorer without any issues.
However, when I deploy this server on dev environment, and try to access the Explorer page with the dev endpoint, I get a few errors.
The app.options() line with cors argument somehow seems to have solved part of them but not all.
Errors I am getting (on Dev Tools console):
Failed to load resource: net::ERR_CERT_AUTHORITY_INVALID
POST https://dev.endpoint.service/graphql net::ERR_CERT_AUTHORITY_INVALID
Errors I am getting (as popups on the Explorer page):
Unable to reach server
To diagnose the problem, please run:
npx diagnose-endpoint#1.0.12 --endpoint=https://dev.endpoint.service/graphql
I've tried running the command as instructed in the error and got this result:
Diagnosing https://dev.endpoint.service/graphql
Could not find any problems with the endpoint. Would you please to let us know about this > at explorer-feedback#apollographql.com
Frankly, I'm not even sure I understand the problem.
Am I getting these errors because, even though I launch an http server of Apollo without certificates, I am trying to access it via an https endpoint (which requires certificates)? I have to do this, service is stored in AKS cluster, which is only accessible through the endpoint I am calling. But every service that is already there is also an http service, not https, and is accessible through this same endpoint.
Also, even though these errors are showing up frequently, I am also able to query the server successfully most of the time on Explorer, and the data returned is exactly what I expected, which makes even less sense.
I am using edge browser but also tried chrome, and have the same issues.
How can an error like this be intermittent?
Without any intervention on my part, sometimes it's like this:
Any help, hints, ideas, please.
Thank you so much.
As much as it pains me to admit, it seems the issue is related to the VPN my company is using.
There were a few tells that pointed in this direction, once I started paying attention:
We can't access the endpoint I mentioned without the VPN turned on.
Other services in the AKS behave with the same error, if being called constantly through the same endpoint. I did not think to do that test at first, but when I realized that on Apollo server, the server is constantly doing the introspection thing to check the schema, it means it is being called more often than the other services that do not have this functionality.
We have some monitoring tools, to check the pod statuses and so on, and nothing indicated any problems in this service, or that it needed any kind of pod escalation (due to excessive number of requests).
I actually performed kubectl portforward test linking my localhost directly to the AKS cluster. Calling the service this way bypasses that endpoint which I am, under normal circumstances, forced to use before the request actually reaches the cluster. And I was simultaneously seeing on one window where I was calling the service the normal way showing that error on Apollo Studio, and at the same time on another Apollo Studio window performing the same request with this portforward bypass mechanic, and the latter was working just fine. If it really was a problem with the service, it would be down for both windows.
Other colleagues were testing the service at the same time as me and they were saying the service was working fine for them, until it wasn't. So every developer on my team could be accessing the service at the same time, and the error would just randomly show up for some, but not for others.
There are long periods where the error doesn't occur at all, like during lunch hours, or after work hours, and I assume the VPN traffic will be much lower during those hours.

Why is my client side code being compiled and ran on node backend?

I'm new to SSR so I'm not sure if this problem and my solution is standard practices but I can't imagine so.
My goal is to have a dynamic page that allows users to add/remove items on the page. I originally programmed this component with the intention of it only being a client side react project but now I want to put it on a server. Now when I'm translating my code to the new project I've run into a couple errors now that has to do with my backend running the code that is only supposed to be run on client side.
For instance I ran into this problem earlier React Redux bundle.js being thrown into request, and I was able to solve this issue with a Janky solution where I make sure that it's being passed client side code and stop the execution of its being passed from the backend. Now I've had to refactor my code to not use the fetch() function because it's not a function that the node backend recognizes and it's now complaining about my use of the document object because that's not a thing in node either.
I can keep on going importing new modules to fix the errors to keep my website from crashing but I feel like I'm on a small boat patching up new holes with duck tape waiting to find the next hole.
Here's an image of my config if that's necessary I also have additional images in my previous stack overflow question (link aobove)
For the bundle.js issue I am not sure to understand why it happens.
For the fetch issue, I think this is a common problem with SSR and if you implement it by yourself you need to handle conditions in different places of your app:
if(!!window) {
// do client-side stuff like accessing
// window.document
}
Basically the most common usage of SSR is to handle the first execution of you app on the server side. This include:
Route resolution
Fetching data (using nodejs http module)
Hydrating stores (if you use redux or other data library)
rendering UI
Once the execution is done, your server returns the bundled js app with hydrated store and UI and returns it to the client. Subsequent requests or route update will be executed on the client side, so you can directly use fetch or react-router
The pros of doing SSR are:
Great first contentful
Great for SEO
Client-side machine do less works
There is a lot of libraries that can help you with SSR as well as frameworks like nextjs, use-http

Intermittent "Cannot GET /" with node.js on Bluemix

For some reason on all my Bluemix services, I intermittently get the error "Cannot GET /pathname" on my node.js express services. This is intermittent (it works about 1/3 of the time). There is no error or logging shown in the application when this happens (however that response is coming from express I assume).
Any ideas? I have no idea how to progress here. The server has ample resources (memory + CPU).
I've seen this happen before when the user accidently has 2 different applications mapped to the same route/URL. The load balancer is hitting a different application on each time.
Try changing the route to something else and try to recreate the problem....myappname2.mybluemix.net
If that seems to fix it, log in to the UI and confirm that you do not have duplicate applications and that all applications have a unique route.

Node web server crash

I'm working on Node + Mongo + Express to create REST API. There are cases when node server gets crashed and I've to restart it again. I'm using forever to do the restart stuff. But I am unable to find the solution for process which are lost during the crash.
Example: I am handling 10 http request at a moment and my node server get crashed for any request. In this case other 9 running request will be lost.
Is there any fallback mechanism to prevent this?
The nearest I see right now would be a NodeJS cluster, which I believe the master will handle the crash of one of his child and move the http request, but, if this does not work then make it with nginx and some node processes at the same time, it will handle that kind of things
Hope it helps you.
The server crashes if there is an unhandled exception, so you need to add error handling to your functions with try catch. There are several events sent to the process objects that can help you with your problem. You could try listening for uncaughtException and then follow a strategy like it's mentioned here: http://blog.argteam.com/coding/hardening-node-js-for-production-part-3-zero-downtime-deployments-with-nginx/, just replace 'SIGTERM'.

Use ExpressJS app via FastCGI

Just started deal with NodeJS web apps and have a fundamental question.
Since i came from the PHP realm, i know PHP have a built-in HTTP server but no one actually use it and we used nginx and in the prehistoric projects Apache as HTTP server, when i came into ExpressJS i found that all examples talking about listening to the HTTP server that ExpressJS open (via http NodeJS module of-course) but no one talking about use it via FastCGI (nginx -> FastCGI (e.g. node-fastcgi) -> my ExpressJS app) like i used to do with PHP (nginx -> PHP-fpm -> my PHP env) and i wonder why?
As far as i understood, NodeJS app is very fast, non-blocking I/O and so on but there is a security hole using the app like everybody show, since the service that run have same common resources in the JavaScript environment, one user can share by mistake (or not) sensitive information with others, for instance. let's assume the developer made a mistake like this:
router.post('/set-user-cc', function(res){
global.user = new User({
creditCard: req.param('cc')
});
});
And other user do request like that:
router.get('/get-user-cc', funciton(req, res){
res.json(global.user);
});
At this point each user will get the user's CC info.
Using my ExpressJS app via FastCGI will open a clean JavaScript environment for each HTTP request and users won't hurt each other.
It'll nice to hear form NodeJS (web) apps experienced developers why no one suggest to use the FastCGI solution (searched on Google and found almost nothing) and if so, why it's too bad?
(p.s. the example is just to demonstrate the problem it's not something that someone actually did, but as we know lot of stupid people exists in the universe :)
Thank you!
You won't do mistakes like that if you lint your code, run under strict mode, and don't use global variables like that.
Also in nodejs web applications you generally want to make the server stateless and keep all the data in the databases. This would also make it a more scalable architecture.
In applications that are security super important, you can throw heavy fuzzy testing at it to find problems like that too.
If you do all this, plus having a strict code review process, you won't have to worry about it at all.
FastCGI doesn't prevent this problem as a single or a few connections is used to communicate with the server that processes the requests(node.js in this case) and HTTP connections are multiplexed through it. A node.js process will handle multiple requests at a time.
You can potentially somehow make a solution that launches a thread but it'll be a lot slower. In case if you are using node.js for things that are required to be have high reliability or can't afford small mistakes(for example health related devices), node.js is the wrong platform for it.

Categories

Resources