Getting MQRC_ENVIRONMENT_ERROR [2012] error after updating to v2.1.0
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;
},
);
}
Guys, this issue is open since two weeks. Can anyone help here please?
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.
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.
Which call is failing open or get ?
open is failing
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.