pouchdb / pouchdb-server

CouchDB-compatible server built on PouchDB and Node
Apache License 2.0
944 stars 155 forks source link

express-pouchdb allocates infinite memory when given a defunct PouchDB #436

Open ben0x539 opened 4 years ago

ben0x539 commented 4 years ago
var http = require('http');
var PouchDB = require('pouchdb');

var app = require('express-pouchdb')(PouchDB.defaults({
  prefix: './non-existent-path/',
}))

app.listen(3000, function() {
  http.get('http://localhost:3000/db/hello'); // delayed explosion
});

(node:13549) UnhandledPromiseRejectionWarning: OpenError: IO error: ./non-existent-path/_replicator/LOCK: No such file or directory

Despite the warning, we continue on with a non-functional pouchdb object backing those routes. When trying to handle a request, this bit of code gets stuck forever while allocating more and more promises:

https://github.com/pouchdb/pouchdb-server/blob/ef24d7d4670fd1b08b9d82778e91e7e0b8936c1c/packages/node_modules/express-pouchdb/lib/routes/authentication.js#L55-L65

After busylooping while growing to a few gigabytes in size, node gets fed up and terminates.

This could probably be mitigated by only using one promise there and only repeating the setImmediate (or even setTimeout) call, but ultimately we should probably just be erroring out earlier and not let it come that far.

It's a very low impact crash that's easily avoided, but jumping into an unfamiliar codebase and not realizing the significance of the above warning, it took me a while to catch on. :)