diff --git a/README.md b/README.md index aa947c61..8f596586 100644 --- a/README.md +++ b/README.md @@ -182,6 +182,19 @@ app.use(session({ })) ``` +##### ignoreErrors + +Setting `ignoreErrors` as true, any errors while fetching the session from the +store will be ignored. If the session is not fetched, the `req.session` will be +undefined. This flag can be used to harden your website against store failures. +In case of failure, the response will not be HTTP 500 Internal Server Error. +However your application code needs to be able to gracefully handle a +non-existing `req.session`. + +Furthermore it's inadvisable to add a temporary fake `req.session` object, since +the connection might fail afterward on the store touch or save calls. As long as +the `req.session` is undefined, the middleware will not save it in the store. + ##### name The name of the session ID cookie to set in the response (and read from in the diff --git a/index.js b/index.js index 175fb234..b4e69f79 100644 --- a/index.js +++ b/index.js @@ -92,6 +92,9 @@ function session(options) { // get the session id generate function var generateId = opts.genid || generateSessionId + // ignore errors when store fails + var ignoreErrors = !!opts.ignoreErrors + // get the session cookie name var name = opts.name || opts.key || 'connect.sid' @@ -463,6 +466,11 @@ function session(options) { debug('error %j', err); if (err.code !== 'ENOENT') { + if (ignoreErrors) { + debug('ignoring fetch error'); + return next(); + } + next(err); return; } diff --git a/test/session.js b/test/session.js index 5f49e352..a3e0f838 100644 --- a/test/session.js +++ b/test/session.js @@ -874,6 +874,30 @@ describe('session()', function(){ }); }); + describe('ignoreErrors option', function(){ + it('should work without session on fetch error', function (done) { + var store = new session.MemoryStore() + var server = createServer({ store: store, ignoreErrors: true }, function (req, res) { + res.end('hello, world') + }) + + store.get = function destroy(sid, callback) { + callback(new Error('boom!')) + } + + request(server) + .get('/') + .expect(shouldSetCookie('connect.sid')) + .expect(200, 'hello, world', function (err, res) { + if (err) return done(err) + request(server) + .get('/') + .set('Cookie', cookie(res)) + .expect(200, 'hello, world', done) + }) + }); + }); + describe('key option', function(){ it('should default to "connect.sid"', function(done){ request(createServer())