louischatriot / nedb

The JavaScript Database, for Node.js, nw.js, electron and the browser
MIT License
13.46k stars 1.03k forks source link

Not very sure if it is a util.promisify() or a NeDB bug (but promisify() from bluebird runs well) #663

Closed teadrinker2015 closed 3 years ago

teadrinker2015 commented 3 years ago

What steps will reproduce the bug?

const { promisify } = require('util')
const Datastore = require('nedb')

async function main() {
    const db = new Datastore({filename:'test.db', autoload:true})
    db.insert({'some':'thing'})
    const findOne = promisify(db.findOne)
    const res = await findOne({})
    console.log(res)
}

main()

Seems the promisify(db.findOne) doesn't behave correctly.

How often does it reproduce? Is there a required condition?

always

What is the expected behavior?

PS D:\extag> node test.js { some: 'thing', _id: 'ReDFQNxyzLAND97K' }

What do you see instead?

PS D:\extag> node test.js (node:16484) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'push' of undefined at Cursor.exec (D:\extag\node_modules\nedb\lib\cursor.js:198:20) at Datastore.findOne (D:\extag\node_modules\nedb\lib\datastore.js:526:12) at internal/util.js:297:30 at new Promise () at internal/util.js:296:12 at main (D:\extag\test.js:10:23) at Object. (D:\extag\test.js:4:1) at Module._compile (internal/modules/cjs/loader.js:1063:30) at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10) at Module.load (internal/modules/cjs/loader.js:928:32) (Use node --trace-warnings ... to show where the warning was created) (node:16484) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag --unhandled-rejections=strict (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 2) (node:16484) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

Additional information

In these two cases below, it will run correctly:

Manually promisify

const Datastore = require('nedb')

function findOne(arg) {
    return new Promise(resolve=>{
        db.findOne(arg, (err, res)=>resolve(res))
    })
}

async function main() {
    const db = new Datastore({filename:'test.db', autoload:true})
    db.insert({'some':'thing'})
    const res = await findOne({})
    console.log(res)
}

main()

Use bluebird.Promise.promisify() instead

const { promisify } = require('bluebird')
const Datastore = require('nedb')

async function main() {
    const db = new Datastore({filename:'test.db', autoload:true})
    db.insert({'some':'thing'})
    const findOne = promisify(db.findOne, {context:db})
    const res = await findOne({})
    console.log(res)
}

main()
teadrinker2015 commented 3 years ago

I foget to bind(db). Didn't know bluebird has a slightly defferent promisify() from node util