mq-mqi-nodejs icon indicating copy to clipboard operation
mq-mqi-nodejs copied to clipboard

Getting MQRC_ENVIRONMENT_ERROR [2012] error after updating to v2.1.0

Open AyushBhadauriaI6 opened this issue 11 months ago • 6 comments

Hello, I recently upgraded my ibmmq package version to v2.1.0 and getting following error while trying to use the Get operation to read messages from the queue

(MQError) GET[async]: MQCC = MQCC_FAILED [2] MQRC = MQRC_ENVIRONMENT_ERROR [2012]

I have able to subscribe to the queue using Get Operation correctly with version v1.0.6. Note, that I have disabled useCtl so that Get operation does not require Ctl to finish reading messages using setTuningParameters({ useCtl: false });

Here is the code block I am using to subscribe to the queue.

    async createSubscription(queueName) {

        const objectDescriptor = new MQOD();
        objectDescriptor.ObjectType = MQC.MQOT_Q;
        objectDescriptor.ObjectName = queueName;

        const queue = await OpenPromise(
            await this.connectionHandle,
            objectDescriptor,
            MQC.MQOO_INPUT_AS_Q_DEF,
        );

        this.logger.debug('createSubscription', { queueName });

        const getMessageOptions = new MQGMO();

        getMessageOptions.Options = (
            MQC.MQGMO_NO_SYNCPOINT |
            MQC.MQGMO_WAIT |
            MQC.MQGMO_FAIL_IF_QUIESCING |
            MQC.MQGMO_CONVERT
        );
        getMessageOptions.MatchOptions = MQC.MQMO_NONE;
        getMessageOptions.WaitInterval = MQC.MQWI_UNLIMITED;
    
        Get(
            queue,
            new MQMD(),
            getMessageOptions,
            (error, ...message) => {
                if (error instanceof Error) {
                    throw new Error(error);
                }

                return message;
            },
        );
    }

AyushBhadauriaI6 avatar Jan 22 '25 13:01 AyushBhadauriaI6

Guys, this issue is open since two weeks. Can anyone help here please?

AyushBhadauriaI6 avatar Feb 03 '25 07:02 AyushBhadauriaI6

await this.connectionHandle looks odd, I would expect the code to be await on a function call that returns a promise.

If you are using a newer version of Node.js, then I think this gets captured as you are expecting it, but it still makes me nervous when I see a capture attempt like this on this. In the earlier versions of Node.js, this inside the async version isn't captured and isn't referring to the object the you think it is and hence this.connectionHandle is some random initialised storage.

In this pattern I would expect either the handle or the this to be captured, before entering the OpenPromise closure. IE.

         let self = this;
        const queue = await OpenPromise(
            self.connectionHandle,
            objectDescriptor,
            MQC.MQOO_INPUT_AS_Q_DEF,
        );

Note : Still no await on self.connectionHandle.

chughts avatar Feb 03 '25 09:02 chughts

Hey @chughts, Thanks for addressing the issue. the connectionHandle is a promise which resolves queue manager. We initialise the manager when the class loads and resolves the manager while subscribing. here is the code to the connection manager.

    async connectManager() {
        const connectionOptions = new MQCNO();
        const channelDefinition = new MQCD();

        channelDefinition.ConnectionName = `${this.host}(${this.port})`;
        channelDefinition.ChannelName = this.channelName;
        channelDefinition.HeartbeatInterval = 30;
        connectionOptions.ClientConn = channelDefinition;
        connectionOptions.Options |= MQC.MQCNO_CLIENT_BINDING;

        try {
            this.connectionHandle = ConnxPromise(
                this.queueManager,
                connectionOptions,
            );

            return this.connectionHandle;
        } catch (error) {
            delete this.connectionHandle;
            throw error;
        }
    }

PS: I am using Node v22.

AyushBhadauriaI6 avatar Feb 12 '25 08:02 AyushBhadauriaI6

Which call is failing open or get ?

chughts avatar Feb 12 '25 11:02 chughts

open is failing

AyushBhadauriaI6 avatar Mar 05 '25 09:03 AyushBhadauriaI6

I think you are going to have to untangle the code a bit to debug it.

As a test try waiting on this.connectionHandle before calling OpenPromise and checking if it is returning a valid handle. If it is then call OpenPromise with the connection handle. See if that works.

chughts avatar Mar 05 '25 09:03 chughts