Commit and Rollback both raise exceptions when used in Promise form.
connection.commit().then(connection.close());
Error: NJS-032: connection cannot be released because a database call is in progress
Use callback form. Example:
connection.commit( () => {connection.close()} );
Affects multiple OS:
@stevenhankin Please provide a reproducible test case which demonstrates the issue.
Given the following table:
create table t (c number);
This works fine:
const oracledb = require('oracledb');
const config = require('./dbConfig.js');
let conn;
oracledb.getConnection(config)
.then(c => {
conn = c;
return conn.execute(
'insert into t (c) values (:num)',
[1]
);
})
.then(r => {
return conn.commit();
})
.then(() => {
return conn.release();
})
.then(() => {
console.log('It worked!');
})
.catch(err => {
console.log('It didn\'t work.', err);
});
@dmcghan If I modify your above example I can cause the error (although the row still adds and commits):
oracledb.getConnection(config).then((conn) => {
conn.execute('insert into t (c) values (:num)', [1],
() => {
conn.commit()
.then(conn.release())
.then(() => console.log('It worked!'))
.catch(err => {
console.log('It didn\'t work.', err);
})
})
});
(node:25187) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error: NJS-032: connection cannot be released because a database call is in progress
It worked!
Ok, it's my bad; I need to make sure the Promise for the commit and close are _returned_ rather than _executed_
@stevenhankin Glad you got it working!
Reviewing your code example, I just wanted to point something out (I was making the same mistake until the following became clear)...
The then method generally accepts two parameters: callback functions for success and error.
When you have something like this:
.then(conn.release())
You're really passing the result of calling an async method (a promise), not a callback function. When values other than callback functions are passed, they are essentially turned into a promise (weird because it already is one in this case) and immediately passed to the next then handler.
Using callback functions instead of values is key because the callback functions are invoked asynchronously, which allows the magic of the next then waiting if the callback returns a promise.
Yep, that's it, thanks @dmcghan :)
@dmcghan what about adding some more promise examples to the repo?
@cjbj Maybe a good idea, though I'm not sure it would have helped much with the two recent issues related to promises.
Most helpful comment
@stevenhankin Glad you got it working!
Reviewing your code example, I just wanted to point something out (I was making the same mistake until the following became clear)...
The
thenmethod generally accepts two parameters: callback functions for success and error.When you have something like this:
You're really passing the result of calling an async method (a promise), not a callback function. When values other than callback functions are passed, they are essentially turned into a promise (weird because it already is one in this case) and immediately passed to the next
thenhandler.Using callback functions instead of values is key because the callback functions are invoked asynchronously, which allows the magic of the next
thenwaiting if the callback returns a promise.