getStatuses() always rejects on devices that fragment the status response (e.g. TM-m30III over LAN)
Thanks for this library! Printer.getStatuses() is unusable against printers that return the four real-time status bytes across multiple
data events instead of one — which includes the Epson TM-m30III over LAN, where each status byte arrives in its own TCP packet.
Environment
@node-escpos/core@0.6.0
@node-escpos/network-adapter@0.0.1
- Node 24
- Hardware: Epson TM-m30III (LAN, port 9100) — validated live
Problem
getStatuses() sends the four DLE EOT queries, then reads only the first data event and rejects unless all four bytes are present
in that single chunk:
// @node-escpos/core – getStatuses()
// reads one 'data' event, then:
// buffer.length < 4 -> reject
Real devices don't guarantee one packet. The TM-m30III sends the four status bytes as four separate data events (observed on the wire:
0x16, 0x12, 0x12, 0x12 in four packets). So the first event carries one byte, the length check fails, and getStatuses() always
rejects — it can never succeed against this printer.
Repro
const { Printer } = require('@node-escpos/core');
const Network = require('@node-escpos/network-adapter').default;
const printer = new Printer(new Network('<m30III-ip>', 9100, 5000));
await new Promise((res, rej) => printer.adapter.open(e => e ? rej(e) : res()));
await printer.getStatuses();
// -> rejects; the first 'data' event has fewer than 4 bytes
Root cause
The reader resolves/rejects on the first data event rather than accumulating until the expected number of bytes has arrived.
Suggested fix
Accumulate bytes across data events until the expected count (4) is reached, with a timeout to bound the wait:
// pseudocode
const bytes = [];
const onData = (buf) => {
for (const b of buf) bytes.push(b);
if (bytes.length >= 4) finish(resolve, bytes.slice(0, 4));
};
const timer = setTimeout(() => finish(reject, new Error('status read timeout')), timeoutMs);
// ...then send the DLE EOT queries
This makes getStatuses() robust to packet fragmentation while remaining correct for devices that do send all four bytes at once.
Workaround
For anyone hitting this: read the status bytes yourself with an accumulating listener (gather across data events until you have 4, then
parse) instead of getStatuses().
getStatuses()always rejects on devices that fragment the status response (e.g. TM-m30III over LAN)Thanks for this library!
Printer.getStatuses()is unusable against printers that return the four real-time status bytes across multipledataevents instead of one — which includes the Epson TM-m30III over LAN, where each status byte arrives in its own TCP packet.Environment
@node-escpos/core@0.6.0@node-escpos/network-adapter@0.0.1Problem
getStatuses()sends the fourDLE EOTqueries, then reads only the firstdataevent and rejects unless all four bytes are presentin that single chunk:
Real devices don't guarantee one packet. The TM-m30III sends the four status bytes as four separate
dataevents (observed on the wire:0x16,0x12,0x12,0x12in four packets). So the first event carries one byte, the length check fails, andgetStatuses()alwaysrejects — it can never succeed against this printer.
Repro
Root cause
The reader resolves/rejects on the first
dataevent rather than accumulating until the expected number of bytes has arrived.Suggested fix
Accumulate bytes across
dataevents until the expected count (4) is reached, with a timeout to bound the wait:This makes
getStatuses()robust to packet fragmentation while remaining correct for devices that do send all four bytes at once.Workaround
For anyone hitting this: read the status bytes yourself with an accumulating listener (gather across
dataevents until you have 4, thenparse) instead of
getStatuses().