how to properly close node-express server?

93,903

Solution 1

app.listen() returns http.Server. You should invoke close() on that instance and not on app instance.

Ex.

app.get(
    '/auth/github/callback',
    passport.authenticate('github', { failureRedirect: '/login' }),
    function(req, res) {
        res.redirect('/');

        setTimeout(function () {
            server.close();
            // ^^^^^^^^^^^
        }, 3000)
    }
);

var server = app.listen('http://localhost:5000/');

You can inspect sources: /node_modules/express/lib/application.js

Solution 2

In express v3 they removed this function.

You can still achieve the same by assigning the result of app.listen() function and apply close on it:

var server = app.listen(3000);
server.close((err) => {
  console.log('server closed')
  process.exit(err ? 1 : 0)
})

https://github.com/visionmedia/express/issues/1366

Solution 3

If any error occurs in your express app then you must have to close the server and you can do that like below-

var app = express();
var server = app.listen(process.env.PORT || 5000)

If any error occurs then our application will get a signal named SIGTERM. You can read more SIGTERM here - https://www.gnu.org/software/libc/manual/html_node/Termination-Signals.html

process.on('SIGTERM', () => {
  console.info('SIGTERM signal received.');
  console.log('Closing http server.');
  server.close((err) => {
    console.log('Http server closed.');
    process.exit(err ? 1 : 0);
  });
});

Solution 4

I have answered a variation of "how to terminate a HTTP server" many times on different support channels. Unfortunately, I couldn't recommend any of the existing libraries because they are lacking in one or another way. I have since put together a package that (I believe) is handling all the cases expected of graceful express.js HTTP(S) server termination.

https://github.com/gajus/http-terminator

The main benefit of http-terminator is that:

  • it does not monkey-patch Node.js API
  • it immediately destroys all sockets without an attached HTTP request
  • it allows graceful timeout to sockets with ongoing HTTP requests
  • it properly handles HTTPS connections
  • it informs connections using keep-alive that server is shutting down by setting a connection: close header
  • it does not terminate the Node.js process
Share:
93,903
Vladimir Starkov
Author by

Vladimir Starkov

Updated on October 10, 2021

Comments

  • Vladimir Starkov
    Vladimir Starkov over 2 years

    I need to close server after getting callback from /auth/github/callback url. With usual HTTP API closing server is currently supporting with server.close([callback]) API function, but with node-express server i’m getting TypeError: Object function app(req, res){ app.handle(req, res); } has no method 'close' error. And I don't know how to find information to solve this problem.
    How should I close express server?

    NodeJS configuration notes:

    $ node --version
    v0.8.17
    $ npm --version
    1.2.0
    $ npm view express version
    3.0.6
    

    Actual application code:

    var app = express();
    
    // configure Express
    app.configure(function() {
        // … configuration
    });
    
    app.get(
        '/auth/github/callback',
        passport.authenticate('github', { failureRedirect: '/login' }),
        function(req, res) {
            res.redirect('/');
    
            setTimeout(function () {
                app.close();
                // TypeError: Object function app(req, res){ app.handle(req, res); } has no method 'close'
            }, 3000)
        }
    );
    
    app.listen('http://localhost:5000/');
    

    Also, I have found ‘nodejs express close…’ but I don't sure if I can use it with code I have: var app = express();.

  • Uday Hiwarale
    Uday Hiwarale almost 8 years
    Strange, it is not closing if I access some route.
  • Rick Velde
    Rick Velde over 7 years
    @Uday, I also experienced this. I found out that my browser had an HTTP1.1 persistant connection open, so when I pressed F5 it appeared as though the server didn't close. If you try a different browser you will see the server socket is not running.
  • Vladimir Starkov
    Vladimir Starkov almost 5 years
    sorry, its not relevant. Question is about manual server shutdown and not about error handling
  • Edison Spencer
    Edison Spencer over 4 years
    That was my mistake, I was calling close on app instead of server. Saved my day. Many thanks 👍
  • Gajus
    Gajus over 4 years
    Use something like github.com/gajus/http-terminator to ensure termination of the server in case there are persistent connections or requests not producing a response.
  • Gajus
    Gajus over 4 years
    It remains a valid question.
  • krupesh Anadkat
    krupesh Anadkat almost 4 years
    short and simple
  • João Pimentel Ferreira
    João Pimentel Ferreira almost 3 years
    why the Timeout?
  • Oleg Valter is with Ukraine
    Oleg Valter is with Ukraine almost 3 years
    @JoãoPimentelFerreira it seems that Vladimir simply followed the example OP gave where they close after 3 seconds
  • João Pimentel Ferreira
    João Pimentel Ferreira almost 3 years
    are you sure server.close has a callback? I don't see it in the documentation
  • Oleg Valter is with Ukraine
    Oleg Valter is with Ukraine almost 3 years
    @JoãoPimentelFerreira - yup, it's certainly there
  • João Pimentel Ferreira
    João Pimentel Ferreira almost 3 years
    @OlegValter thanks but I read that expressJs server does not inherit anymore from nodejs http-server
  • Oleg Valter is with Ukraine
    Oleg Valter is with Ukraine almost 3 years
    @JoãoPimentelFerreira last time I checked, app.listen call still does: "The app.listen() method returns an http.Server object and (for HTTP) is a convenience method for the following"