asfernandes / node-firebird-drivers

Node.js Firebird Drivers
MIT License
53 stars 17 forks source link

bug: unhandled exception - executeQuery #139

Closed Tomas2D closed 8 months ago

Tomas2D commented 8 months ago

The following code throws an unhandled exception, but it should throw just an exception. In case I correctly use the executeSingleton or executeSingletonAsObject, it works. But from my perspective, the executeQuery should work because the statement.hasResultSet === true.

Besides that, I assume that executeQuery should work. Thanks.

import { createNativeClient, getDefaultLibraryFilename } from 'node-firebird-driver-native';

async function test() {
    const client = createNativeClient(getDefaultLibraryFilename());
    const attachment = await client.createDatabase(
        'localhost/3050:/tmp/test.fdb',
        { username: "SYSDBA", password: "masterkey"}
    );
    const transaction = await attachment.startTransaction();

    const statement = await attachment.prepare(transaction, 'SELECT 1 FROM  RDB$DATABASE');
    try {
        // this will throw an unhandled exception
        await statement.executeQuery(transaction);
    } catch {
        console.info('this is never called, but it should be');
    }

    await transaction.commit();
    await attachment.dropDatabase();
    await client.dispose();
}

test().then(() => console.log('Finish...'));
asfernandes commented 8 months ago

Could you please be more specific? Why you say that query must use executeSingleton or executeSingletonAsObject to be correctly? Why the given code would be problematic? Isn't it a correct code as the ones used in many tests present in the package?

asfernandes commented 8 months ago

Is it because only the returned result set isn't closed?

asfernandes commented 8 months ago

Why the catch block should be called?

Tomas2D commented 8 months ago

Just run the code, and you will see it.

This line await statement.executeQuery(transaction); triggers the unhandled exception even if it's wrapped in a try/catch block. If I replace the mentioned line with await statement.executeSingleton(transaction) works (no error is thrown).

Why you say that query must use executeSingleton or executeSingletonAsObject to be correctly?

I just assume this because otherwise, the script crashes.

Why the catch block should be called?

Because it's in the try/catch block.

asfernandes commented 8 months ago

Cannot reproduce. This test correctly print Finish... for me. If you have different result, then you should prepare test case that shows the incorrect behavior.

Tomas2D commented 7 months ago

Sorry, the problem was somewhere else. However, the behaviour is not consistent between macOS and Linux. If I do not close the statement explicitly, I receive [Error: Invalid resultset interface] error - only on Linux, not on macOS.

import { createNativeClient, getDefaultLibraryFilename } from 'node-firebird-driver-native';

async function test() {
    const client = createNativeClient(getDefaultLibraryFilename());
    const attachment = await client.createDatabase(
        'localhost/3050:/tmp/test.fdb',
        { username: "SYSDBA", password: "masterkey"}
    );
    const transaction = await attachment.startTransaction();

    const statement = await attachment.prepare(transaction, 'SELECT 1 FROM  RDB$DATABASE');
    await statement.executeQuery(transaction);

        // If I do not add this line, the program prints the following error message and halts (only on Linux Debian 10, not macOS)
        // [Error: Invalid resultset interface]
        await statement.close()

        await transaction.commit();
    await attachment.dropDatabase();
    await client.dispose();
}

test().then(() => console.log('Finish...'));
asfernandes commented 7 months ago

There is not even method statement.close(). It's dispose.

Tomas2D commented 7 months ago

Yes, so 'dispose'. I did not double-check before posting. This does not change anything.

asfernandes commented 7 months ago

For me too. No problem happens