serialport / node-serialport

Access serial ports with JavaScript. Linux, OSX and Windows. Welcome your robotic JavaScript overlords. Better yet, program them!
https://serialport.io
MIT License
5.75k stars 1k forks source link

Enable Strict Errors on Unix #2466

Open rroessler opened 2 years ago

rroessler commented 2 years ago

Allow Strict Unix Errors to FAIL

Currently, the Unix errors "EAGAIN", "EWOULDBLOCK" and "EINTR" result in write methods to try again. It would be good to expose these errors for some applications.

Motivation

When working with a USB to TTL port, I currently have to poll my device to ensure it is alive. If polling receives no acknowledgement, the port is still written to. In doing so, this resulted in "EAGAIN" errors that are only viewable in debug mode. Since the default behaviour is to try again, this resulted in a weird echo on the "data" channel. For my application, this behaviour resulted in "ghost" data from the echoes received. Having a flag to specify stricter errors, would allow for catching "EAGAIN" errors that are needed when polling devices in this way.

Pitch

This would require adding a "strictErrors" boolean to the "OpenOptions" interface, adding this to the mock bindings, and finally querying this value in the "unix-write" file.

reconbot commented 2 years ago

Would a read timeout work? And a timeout of 0 wouldn't retry at all?

rroessler commented 2 years ago

That could most likely work. Below is the test script I've been working with to show the issue.

const { SerialPort, DelimiterParser } = require('serialport');

const port = new SerialPort({ path: "...", baudRate: 115200, autoOpen: false });

const parser = port.pipe(new DelimiterParser({ delimiter: '\n' }));
parser.on('data', (chunk) => console.log("Received:", `"${chunk.toString()}"`);
port.on('error', (err) => console.log("Error:", err.message));

(async() => {
    await new Promise((resolve) => port.open(resolve));

    while (true) {
        await new Promise((resolve) => setTimeout(resolve, 1000));
        await new Promise((resolve) => port.write("TEST\n", resolve));
        await new Promise((resolve) => port.drain(resolve));
        console.log("Message Written!");
    }
})();

For some odd reason, after running for a while (about 10+ polls), the sent message begins being echoed.