Skip to content

Commit

Permalink
Remove the disconnect event
Browse files Browse the repository at this point in the history
  • Loading branch information
reconbot committed Jul 10, 2017
1 parent 1888efc commit 2045d85
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 48 deletions.
16 changes: 3 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,6 @@ In addition to reading the [article mentioned above](http://www.voodootikigod.co
* [`Event: "error"`](#module_serialport--SerialPort+event_error)
* [`Event: "open"`](#module_serialport--SerialPort+event_open)
* [`Event: "data"`](#module_serialport--SerialPort+event_data)
* [`Event: "disconnect"`](#module_serialport--SerialPort+event_disconnect)
* [`Event: "close"`](#module_serialport--SerialPort+event_close)
* _static_
* [`.Binding`](#module_serialport--SerialPort.Binding) : [<code>BaseBinding</code>](#module_serialport--SerialPort..BaseBinding)
Expand Down Expand Up @@ -421,7 +420,7 @@ You should never have to wrap a Node-Serialport object in a try/catch statement

### SerialPort ⏏
**Kind**: Exported class
**Emits**: [<code>open</code>](#module_serialport--SerialPort+event_open), [<code>data</code>](#module_serialport--SerialPort+event_data), [<code>close</code>](#module_serialport--SerialPort+event_close), [<code>error</code>](#module_serialport--SerialPort+event_error), [<code>disconnect</code>](#module_serialport--SerialPort+event_disconnect)
**Emits**: [<code>open</code>](#module_serialport--SerialPort+event_open), [<code>data</code>](#module_serialport--SerialPort+event_data), [<code>close</code>](#module_serialport--SerialPort+event_close), [<code>error</code>](#module_serialport--SerialPort+event_error)
**Properties**

| Name | Type | Description |
Expand Down Expand Up @@ -493,7 +492,7 @@ The write operation is non-blocking. When it returns, data might still not have

Some devices, like the Arduino, reset when you open a connection to them. In such cases, immediately writing to the device will cause lost data as they wont be ready to receive the data. This is often worked around by having the Arduino send a "ready" byte that your Node program waits for before writing. You can also often get away with waiting around 400ms.

If a port is disconnected during a write, the write will error in addition to the disconnect event.
If a port is disconnected during a write, the write will error in addition to the `close` event.

Even though serialport is a stream, when writing it can accept arrays of bytes in addition to strings and buffers. This extra functionality is pretty sweet.

Expand Down Expand Up @@ -668,19 +667,10 @@ The `data` event puts the port in flowing mode. Data is emitted as soon as it's

* * *

<a name="module_serialport--SerialPort+event_disconnect"></a>

#### `Event: "disconnect"`
The `disconnect` event's callback is called with an error object. This will always happen before a `close` event if a disconnection is detected. If a disconnect happens and there is no event handler for the disconnect event an error event will be emitted instead. The error will have the `disconnected` property set to `true`.

**Kind**: event emitted by [<code>SerialPort</code>](#exp_module_serialport--SerialPort)

* * *

<a name="module_serialport--SerialPort+event_close"></a>

#### `Event: "close"`
The `close` event's callback is called with no arguments when the port is closed. In the event of an error, an error event is triggered.
The `close` event's callback is called with no arguments when the port is closed. In the case of a disconnect it will be called with a Disconnect Error object (`err.disconnected == true`). In the event of a close error (unlikely), an error event is triggered.

**Kind**: event emitted by [<code>SerialPort</code>](#exp_module_serialport--SerialPort)

Expand Down
2 changes: 2 additions & 0 deletions UPGRADE_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ Upgrading from 4.x to 5.x
-------------
5.x is a major rewrite to make node serialport a NodeJS stream. While the api surface is similar there have been a number of changes to ensure more consistent error handling and operation of a serial port.

- Removed the `disconnect` event. The `close` event now fires with a disconnect error object in the event of a disconnection.

The exact changes will go here see #1046

Upgrading from 3.x to 4.x
Expand Down
27 changes: 8 additions & 19 deletions lib/serialport.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,6 @@ function allocNewReadPool(poolSize) {
* @emits module:serialport#data
* @emits module:serialport#close
* @emits module:serialport#error
* @emits module:serialport#disconnect
* @alias module:serialport
*/
function SerialPort(path, options, callback) {
Expand Down Expand Up @@ -278,7 +277,7 @@ The write operation is non-blocking. When it returns, data might still not have
Some devices, like the Arduino, reset when you open a connection to them. In such cases, immediately writing to the device will cause lost data as they wont be ready to receive the data. This is often worked around by having the Arduino send a "ready" byte that your Node program waits for before writing. You can also often get away with waiting around 400ms.
If a port is disconnected during a write, the write will error in addition to the disconnect event.
If a port is disconnected during a write, the write will error in addition to the `close` event.
Even though serialport is a stream, when writing it can accept arrays of bytes in addition to strings and buffers. This extra functionality is pretty sweet.
* @method module:serialport#write
Expand Down Expand Up @@ -379,30 +378,18 @@ SerialPort.prototype._read = function(bytesToRead) {
});
};

/**
* The `disconnect` event's callback is called with an error object. This will always happen before a `close` event if a disconnection is detected. If a disconnect happens and there is no event handler for the disconnect event an error event will be emitted instead. The error will have the `disconnected` property set to `true`.
* @event module:serialport#disconnect
*/

SerialPort.prototype._disconnected = function(err) {
if (!this.isOpen) {
debug('disconnected aborted because already closed', err);
return;
}
debug('disconnected', err);
err.disconnected = true;

if (this.listeners('disconnect').length > 0) {
this.emit('disconnect', err);
} else {
this.emit('error', err);
}

this.close();
this.close(null, err);
};

/**
* The `close` event's callback is called with no arguments when the port is closed. In the event of an error, an error event is triggered.
* The `close` event's callback is called with no arguments when the port is closed. In the case of a disconnect it will be called with a Disconnect Error object (`err.disconnected == true`). In the event of a close error (unlikely), an error event is triggered.
* @event module:serialport#close
*/

Expand All @@ -413,7 +400,9 @@ SerialPort.prototype._disconnected = function(err) {
* @param {errorCallback} callback Called once a connection is closed.
* @emits module:serialport#close
*/
SerialPort.prototype.close = function(callback) {
SerialPort.prototype.close = function(callback, disconnectError) {
disconnectError = disconnectError || null;

if (!this.isOpen) {
debug('close attempted, but port is not open');
return this._asyncError(new Error('Port is not open'), callback);
Expand All @@ -422,8 +411,8 @@ SerialPort.prototype.close = function(callback) {
this.closing = true;
this.binding.close().then(() => {
this.closing = false;
this.emit('close');
if (callback) { callback.call(this, null) }
this.emit('close', disconnectError);
if (callback) { callback.call(this, disconnectError) }
}, (err) => {
this.closing = false;
debug('Binding #close had an error', err);
Expand Down
21 changes: 5 additions & 16 deletions test/serialport.js
Original file line number Diff line number Diff line change
Expand Up @@ -871,29 +871,18 @@ describe('SerialPort', () => {
});
});

describe('disconnect errors', () => {
it('emits as a disconnect event on a bad read', (done) => {
describe('disconnect close errors', () => {
it('emits as a disconnected close event on a bad read', (done) => {
const port = new SerialPort('/dev/exists');
sinon.stub(port.binding, 'read').callsFake(() => {
return Promise.reject(new Error('EBAD_ERR'));
});
port.on('disconnect', (err) => {
assert.instanceOf(err, Error);
done();
});
port.on('error', done);
port.read();
});

it('emits as an error event if there are no listeners', (done) => {
const port = new SerialPort('/dev/exists');
sinon.stub(port.binding, 'read').callsFake(() => {
return Promise.reject(new Error('attack ships on fire off the shoulder of Orion'));
});
port.on('error', (err) => {
port.on('close', (err) => {
assert.instanceOf(err, Error);
assert.isTrue(err.disconnected);
done();
});
port.on('error', done); // this shouldn't be called
port.read();
});
});
Expand Down

0 comments on commit 2045d85

Please sign in to comment.