cmseaton42 / node-ethernet-ip

A Lightweight Ethernet/IP API written to interface with Rockwell ControlLogix/CompactLogix Controllers.
MIT License
265 stars 106 forks source link

Uncaught Index Out of Range Error #46

Open ajcanterbury opened 5 years ago

ajcanterbury commented 5 years ago

Current Behavior

RangeError: Index out of range (Most recent call first) at checkOffset (buffer.js line 977 col 11) at Uint8Array.Buffer.readUInt16LE (buffer.js line 1023 col 5) at Object.header.parse.buf [as parse] (/opt/losant/node_modules/ethernet-ip/src/enip/encapsulation/index.js line 227 col 26) commandCode: buf.readUInt16LE(0), at Controller._handleDataEvent (/opt/losant/node_modules/ethernet-ip/src/enip/index.js line 240 col 41) const encapsulatedData = header.parse(data); at emitOne (events.js line 116 col 13) at Controller.emit (events.js line 211 col 7) at addChunk (_stream_readable.js line 263 col 12) at readableAddChunk (_stream_readable.js line 250 col 11) at Controller.Readable.push (_stream_readable.js line 208 col 10) at TCP.onread (net.js line 601 col 20)

Expected Behavior

Possible Solution (Optional)

Add a check maybe.

Context

Interrupts multiple reads.

Steps to Reproduce (for bugs only)

Random occurrence, not exactly sure how to reproduce (know that sucks). In a three second loop reading a Group of Tags.

Your Environment

cmseaton42 commented 5 years ago

Okay, can you share the snippet of code that seems to be causing the issue. This is a new one so I'd like to gather a little more context.

Thanks :smile:

ajcanterbury commented 5 years ago

I don't know where this is coming from exactly. Most of the time everything works great. The error is random and not frequent.

I create a connection and then every three seconds I create a tag, read it, add that number of tags to a tag group, read it, then write to the tag group. Sort of like so:

// client.PLC Controller() and client.group TagGroup() is created the first time before the 3 sec loop
const strLen = new Tag('myTag.LEN', 'myProgram', DINT);
try {
  await client.PLC.readTag(strLen);
} catch (err) {
   throw err;
}

// first I clean out the old .DATA before adding the new to the group
client.group.forEach((oldTag) => {
  if (oldTag.name.includes(`myTag.DATA[`)) {
    client.group.remove(oldTag);
  }
});
for (let i=0; i<strLen[newTag].value; i++) {
  client.group.add(new Tag(`myTag.DATA[${i}]`, 'myProgram'));
}
// there are various other tags added to the group I'm leaving out
try {
  await client.PLC.readTagGroup(client.group);
} catch (err) {
  throw err;
}

// the writing is much more involved since data is coming from a separate source but for simplicity
const someText = 'Hello';
client.group.forEach((tag) => {
  charIndex = parseInt(tag.name.substring(tag.name.indexOf('.DATA[')+6, tag.name.length - 1), 10);
  tag.value = someText.charCodeAt(charIndex);
}

try {
  await client.PLC.writeTagGroup(client.group);
} catch (err) {
  throw err;
}

Sorry I don't have much more. The error could also be coming directly after the connect or shutdown.

jhenson29 commented 5 years ago

This looks familiar. I was getting some weird error (I think this one) and I think it came down to group reads with a bad tag, but it was a while ago so I can’t be sure.

I’m in the habit now of always reading tags individually first to check that they work, then only adding them to a group if they were successful on the individual read.

cmseaton42 commented 5 years ago

@ajcanterbury Did you double to check to make sure every tag in the group read existed? If so, did this help resolve the issue?

ajcanterbury commented 5 years ago

I've not been able to link this error to a bad tag, not that this is not the case. There were multiple tests being performed when I saw this uncaught error. The problem is that I believe it would be very inefficient to check each individual tag programmatically since my group can be very large.

cmseaton42 commented 5 years ago

hmmmm, so you would prefer an option to let the group fail silently in the case that a bad tag is detected. Possibly auto-remove the bad tag from the group? just thinking out loud

ajcanterbury commented 5 years ago

Auto-remove could work if that's possible. Easy fix might be to throw an error for a bad buffer message and allowing the read to fail.

gfcittolin commented 5 years ago

hmmmm, so you would prefer an option to let the group fail silently in the case that a bad tag is detected. Possibly auto-remove the bad tag from the group? just thinking out loud

Something like this might be a good idea. The Node-RED node for this library currently have issues in this case, as if there's a single tag that cannot be read, the whole reading fail. I even have a script to read a list of them individually, so I can check before reading them in a group. Dropping them out of the group and emitting an event to signalize it would make it much easier :)