Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix bug in callback-to-promise with varying argument lengths (#103)
This was a latent bug that was exposed after some testing, but is not new. We use an internal function, `callbackToPromise`, to allow functions to be in "callback mode" or "promise mode": myTable.create({foo: 'boo'}, (err, record) => { // ... }); const record = myTable.create({foo: 'boo'}); When calling `callbackToPromise`, you can specify an optional `callbackArgIndex`. If it's unspecified (which it usually is), the callback index is assumed to be the last argument. However, it had a bug. The logic I stated above, "the callback index is assumed to be the last argument", wasn't done every time, but only the _first_ time. That meant that something like this would fail: function sum(a, b, maybeC, callback) { let c; if (callback === undefined) { callback = maybeC; c = 0; } else { c = maybeC; } callback(null, a + b + c); } const wrapped = callbackToPromise(sum, null); // In the following call, the callback arg index is the 3rd argument, // which is correct. wrapped(1, 2, () => { // In the following call, the callback arg index is STILL the 3rd // argument, which is 5--that's incorrect. This would then return // a Promise, which is unexpected, and never call the callback. wrapped(3, 4, 5, () => { // This is never called! }); }); This wasn't just theoretical. This hangs forever on `[email protected]` (make sure to fill in real values): const myTable = new Airtable({apiKey: 'key123'}) .base('app123') .table('My Table'); myTable.create({foo: 'bar'}, (err1) => { if (err1) { throw err1; } myTable.create({foo: 'baz'}, {typecast: true}, (err2) => { // The record is created but this callback is never called // because the second call to `myTable.create` returned a // Promise. }); }); I've made sure to add tests for `callbackToPromise` as part of this commit.
- Loading branch information