2

I set up my nodejs app with qldb to implement a wallet service. Set up some tests with some success tests and some expected error tests and once in a while this error 'BadRequestException: no open transaction' would happen and cause my tests to fail. if I run the test again, they will pass. Again once in a while, this error will happen unexpectedly cause the tests to fail. I noted when commented out my expected error tests and the error didn't happen or did not happen as often. and this error happens not only to the expected error test but to the successful tests. this is how my tests look like

describe('createWallet()', () => {
        it('should return an object with wallet Id', async () => {
            let result6 = await controller.createWallet({ body: mocks.walletInfo6.info });
            documentId6 = result6.walletId;
            expect(result6).to.have.property('walletId').that.is.a.uuid;
        });

        it('One player should have only one active wallet for each currency', async () => {
            try {
                let res = await controller.createWallet({ body: mocks.walletInfo1.info });
                assert.fail('expected error was not thrown')
            } catch (e) {

                expect(e.message).to.equal('Player already owns an active wallet in this currency.');
            }
        });
    });

    describe('suspendWallet()', () => {
        it('should change wallet status to suspend', async () => {
            let res = await controller.suspendWallet({ documentId: documentId3 });
            await controller.suspendWallet({ documentId: documentId5 });
            expect(res).to.be.a.string;
            expect(res).to.equal(documentId3);
        });
        it('should not change wallet status if wallet Id is invalid', async () => {
            try {
                let res = await controller.suspendWallet({ documentId: mocks.invalidWalletId });
                assert.fail('expected error was not thrown')
            } catch (e) {
                expect(e.message).to.equal('Did not find any record with this document Id.');
            }
        });
    });
Saurabh
  • 88
  • 4
Kim Luu
  • 91
  • 5
  • Can you share the code where you are executing transactions using the driver ? Also please let us know the version of the driver. – Saurabh Feb 20 '21 at 21:59
  • Thanks for reporting this Kim! This error can only happen if you attempt to carry out any operation which should take place inside a transaction, such as querying a table, fetching results, or committing a transaction. Are you using a QLDB driver (such as the node-js driver) to execute your calls to QLDB? Or are you using the AWS QLDB SDK API directly? As @saurabh mentioned, if you can share the version and type of system you are using to talk to QLDB, that will help to diagnose the problem :). – alpian Feb 22 '21 at 06:21

2 Answers2

2

It's hard to be certain about how your application is running into this error without looking at how the driver is being used to execute transactions.

The driver APIs (for example - execute ) returns a promise. One way the application could be seeing the "No transaction open error" is that the promise is not resolved before sending further commands.

Cookbook - Refer to the QLDB JS driver cookbook which lists code sample for CRUD operations. Note how the samples use await inside the transactions to wait for the promises to resolve. Not waiting for the promises returned by execute can cause the driver to commit the transaction before the execute call is processed and hence a "No open transaction error".

Sample code for executing transactions -

var qldb = require('amazon-qldb-driver-nodejs');

const qldbDriver = new qldb.QldbDriver("vehicle-registration");

(async function() {
    await qldbDriver.executeLambda(async (txn) => {
        await txn.execute("CREATE TABLE Person");
    });
})();

In case you still face issues, please share the code snippet where you use the driver to execute transactions.

Saurabh
  • 88
  • 4
1

Update on this issue. I use nodejs driver version 2.1.0. My team and I found out that the problem was because there are rollbacks that happen after the error tests and we don't know when the rollbacks are done. When the rollback of the previous test is still running, the transaction for that test is still open so if the next test tries to open a new transaction it would conflict and would not able to open a new transaction for the next test. To fix this, we just not throw errors inside the transaction to prevent rollbacks to happen. This way works for our code, but a better solution would be a way to detect when the rollback is done from the driver and wait for the transaction to close before opening a new transaction.

Kim Luu
  • 91
  • 5