Skip to content

Commit

Permalink
Remove the serial port factory and throw errors on invalid arguments
Browse files Browse the repository at this point in the history
 - Constructor now throws errors when given invalid options
 - The Constructor’s callback is given to `.open()` if `openImmediately` is set
  • Loading branch information
reconbot committed May 24, 2016
1 parent 079777b commit c645996
Show file tree
Hide file tree
Showing 10 changed files with 100 additions and 80 deletions.
32 changes: 15 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,8 +160,8 @@ npm rebuild --build-from-source
Opening a serial port:

```js
var SerialPort = require("serialport").SerialPort
var serialPort = new SerialPort("/dev/tty-usbserial1", {
var SerialPort = require("serialport");
var port = new SerialPort("/dev/tty-usbserial1", {
baudrate: 57600
});
```
Expand All @@ -181,7 +181,7 @@ Constructing a `SerialPort` object will open a port, eventually. You can bind ev


```js
var SerialPort = require('serialport').SerialPort;
var SerialPort = require('serialport');
var port = new SerialPort('/dev/tty-usbserial1');

port.on('open', function () {
Expand All @@ -196,7 +196,7 @@ port.on('open', function () {

This could be moved to the constructor's callback.
```js
var SerialPort = require('serialport').SerialPort;
var SerialPort = require('serialport');
var port = new SerialPort('/dev/tty-usbserial1', function () {
port.write('main screen turn on', function(err) {
if (err) {
Expand All @@ -210,7 +210,7 @@ var port = new SerialPort('/dev/tty-usbserial1', function () {
When disabling the `openImmediately` flag you'll need to open the port on your own. Note, in order to disable the `openImmediately` flag, we have to pass an options object.

```js
var SerialPort = require('serialport').SerialPort;
var SerialPort = require('serialport');
var port = new SerialPort('/dev/tty-usbserial1', {}, false);

port.open(function (err) {
Expand Down Expand Up @@ -246,8 +246,8 @@ Retrieves a list of available serial ports with metadata.
```

```js
var serialPort = require('serialport');
serialPort.list(function (err, ports) {
var SerialPort = require('serialport');
SerialPort.list(function (err, ports) {
ports.forEach(function(port) {
console.log(port.comName);
console.log(port.pnpId);
Expand All @@ -261,22 +261,20 @@ serialPort.list(function (err, ports) {
Out of the box, node-serialport provides two parsers one that simply emits the raw buffer as a data event and the other which provides familiar "readline" style parsing. To use the readline parser, you must provide a delimiter as such:

```js
var serialport = require('serialport');
var SerialPort = serialport.SerialPort;
var SerialPort = require('serialport');

var port = new SerialPort('/dev/tty-usbserial1', {
parser: serialport.parsers.readline('\n')
parser: SerialPort.parsers.readline('\n')
});
```

To use the raw parser, you just provide the function definition (or leave undefined):

```js
var serialport = require('serialport');
var SerialPort = serialport.SerialPort;
var SerialPort = require('serialport');

var port = new SerialPort('/dev/tty-usbserial1', {
parser: serialport.parsers.raw
parser: SerialPort.parsers.raw
});
```

Expand All @@ -300,9 +298,9 @@ Enjoy and do cool things with this code.

## Methods

### SerialPort (path, options, openImmediately, callback)
### SerialPort (path, options, openImmediately, openCallback)

Create a new serial port on `path`.
Create a new serial port on `path`. In the case of invalid arguments or invalid options constructing a new serialport will throw an error. If `openImmediately` is true (the default) the `openCallback` will be passed to `.open()`

**_path_**

Expand Down Expand Up @@ -333,7 +331,7 @@ These properties are ignored for windows. An object with the following propertie

**_openImmediately (optional)_**

Attempts to open a connection to the serial port on `process.nextTick`. The default is `true`. Set to `false` to manually call `open()` at a later time, but note you'll need to use factory error listener in the case of constructor errors.
Attempts to open a connection to the serial port on `process.nextTick`. The default is `true`. If you've provided a `openCallback` it will be given to `open()`. Set to `false` to manually call `open()`.

**_callback (optional)_**

Expand Down Expand Up @@ -435,7 +433,7 @@ Called once the port's flags have been set. `results` are the return of the unde

### .update (options, callback)

Changes the baudrate for an open port. Doesn't yet work on windows.
Changes the baudrate for an open port. Throws if you provide a bad argument. Emits an error or calls the callback if the baud rate isn't supported. Doesn't yet work on windows.

**_options_**

Expand Down
6 changes: 3 additions & 3 deletions bin/serialport-terminal.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env node
'use strict';

var serialport = require('../');
var Serialport = require('../');
var version = require('../package.json').version;
var args = require('commander');

Expand All @@ -21,7 +21,7 @@ args
.parse(process.argv);

function listPorts() {
serialport.list(function(err, ports) {
Serialport.list(function(err, ports) {
if (err) {
console.error('Error listing ports', err);
} else {
Expand Down Expand Up @@ -49,7 +49,7 @@ var openOptions = {
stopBits: args.stopbits
};

var port = new serialport.SerialPort(args.port, openOptions);
var port = new Serialport(args.port, openOptions);

process.stdin.resume();
process.stdin.setRawMode(true);
Expand Down
2 changes: 1 addition & 1 deletion examples/drain.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use strict';

var SerialPort = require('serialport').SerialPort;
var SerialPort = require('serialport');
var port = new SerialPort('/dev/cu.Cubelet-RGB');

port.on('open', function() {
Expand Down
6 changes: 3 additions & 3 deletions examples/opening.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

// Open event example

// var SerialPort = require('serialport').SerialPort;
// var SerialPort = require('serialport');
// var port = new SerialPort('/dev/tty-usbserial1');

// port.on('open', function () {
Expand All @@ -18,7 +18,7 @@

// Constructor callback example

// var SerialPort = require('serialport').SerialPort;
// var SerialPort = require('serialport');
// var port = new SerialPort('/dev/tty-usbserial1', function () {
// port.write('main screen turn on', function(err) {
// if (err) {
Expand All @@ -30,7 +30,7 @@

// When disabling open immediately.

// var SerialPort = require('serialport').SerialPort;
// var SerialPort = require('serialport');
// var port = new SerialPort('/dev/tty-usbserial1', {}, false);

// port.open(function (err) {
Expand Down
53 changes: 22 additions & 31 deletions lib/serialport.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,10 @@ var SerialPortBinding = require('./bindings');
var parsers = require('./parsers');

// Built-ins Dependencies
var EventEmitter = require('events').EventEmitter;
var fs = require('fs');
var stream = require('stream');
var util = require('util');

// Setup the factory
var factory = new EventEmitter();
factory.parsers = parsers;
factory.list = SerialPortBinding.list;

// VALIDATION ARRAYS
var DATABITS = [5, 6, 7, 8];
var STOPBITS = [1, 1.5, 2];
Expand Down Expand Up @@ -96,41 +90,37 @@ function SerialPort(path, options, openImmediately, callback) {
}

stream.Stream.call(this);
callback = callback || function(err) {
if (err) {
if (this._events.error) {
this.emit('error', err);
} else {
factory.emit('error', err);
}
}
}.bind(this);

if (!path) {
return callback(new Error('Invalid port specified: ' + path));
throw new TypeError('No path specified');
}

this.path = path;

var correctedOptions = correctOptions(options);
var settings = assign({}, defaultSettings, correctedOptions);

if (typeof settings.baudRate !== 'number') {
throw new TypeError('Invalid "baudRate" must be a number got: ' + settings.baudRate);
}

if (DATABITS.indexOf(settings.dataBits) === -1) {
return callback(new Error('Invalid "databits": ' + settings.dataBits));
throw new TypeError('Invalid "databits": ' + settings.dataBits);
}

if (STOPBITS.indexOf(settings.stopBits) === -1) {
return callback(new Error('Invalid "stopbits": ' + settings.stopbits));
throw new TypeError('Invalid "stopbits": ' + settings.stopbits);
}

if (PARITY.indexOf(settings.parity) === -1) {
return callback(new Error('Invalid "parity": ' + settings.parity));
throw new TypeError('Invalid "parity": ' + settings.parity);
}

for (var i = FLOWCONTROLS.length - 1; i >= 0; i--) {
if (typeof settings[FLOWCONTROLS[i]] !== 'boolean') {
return callback(new Error('Invalid "' + FLOWCONTROLS[i] + '" is not boolean'));
FLOWCONTROLS.forEach(function(control) {
if (typeof settings[control] !== 'boolean') {
throw new TypeError('Invalid "' + control + '" is not boolean');
}
}
});

// TODO remove this option
settings.dataCallback = options.dataCallback || function(data) {
Expand Down Expand Up @@ -162,13 +152,11 @@ function SerialPort(path, options, openImmediately, callback) {
this.options = settings;

if (openImmediately) {
process.nextTick(function() {
this.open(callback);
}.bind(this));
// is nextTick necessary?
process.nextTick(this.open.bind(this, callback));
}
}

factory.SerialPort = SerialPort;
util.inherits(SerialPort, stream.Stream);

SerialPort.prototype._error = function(error, callback) {
Expand Down Expand Up @@ -218,9 +206,6 @@ SerialPort.prototype.open = function(callback) {
}.bind(this));
};

// underlying code is written to update all options, but for now
// only baud is respected as I don't want to duplicate all the option
// verification code above
SerialPort.prototype.update = function(options, callback) {
if (!this.isOpen()) {
debug('update attempted, but port is not open');
Expand Down Expand Up @@ -493,4 +478,10 @@ SerialPort.prototype.drain = function(callback) {
}.bind(this));
};

module.exports = factory;
SerialPort.parsers = parsers;
SerialPort.list = SerialPortBinding.list;

// TODO deprecate
SerialPort.SerialPort = SerialPort;

module.exports = SerialPort;
5 changes: 2 additions & 3 deletions test/arduinoTest/integration.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
'use strict';
var crypto = require('crypto');
var assert = require('chai').assert;
var serialPort = require('../../');
var SerialPort = serialPort.SerialPort;
var SerialPort = require('../../');

var platform;
switch (process.platform) {
Expand All @@ -24,7 +23,7 @@ if (!testPort) {

describe('SerialPort Integration tests', function() {
it('.list', function(done) {
serialPort.list(function(err, ports) {
SerialPort.list(function(err, ports) {
var foundPort = false;
ports.forEach(function(port) {
if (port.comName === testPort){
Expand Down
2 changes: 1 addition & 1 deletion test/arduinoTest/serialDuplexTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Tests the functionality of the serial port library.
To be used in conjunction with the Arduino sketch ArduinoEcho.ino
*/
'use strict';
var SerialPort = require('../../').SerialPort;
var SerialPort = require('../../');
var args = require('commander');

args
Expand Down
6 changes: 3 additions & 3 deletions test/arduinoTest/stress.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

var assert = require('chai').assert;
var util = require('util');
var serialPort = require('../../');
var SerialPort = require('../../');
require('colors'); // this modifies String.prototype
// var fs = require('fs');

Expand Down Expand Up @@ -34,7 +34,7 @@ describe('the stress', function() {
it("doesn't leak memory", function(done) {
var data = new Buffer(1024);
var hd = new memwatch.HeapDiff();
var port = new serialPort.SerialPort(testPort, {}, false);
var port = new SerialPort(testPort, {}, false);
port.on('close', done);

var leaks = 0;
Expand Down Expand Up @@ -87,7 +87,7 @@ describe('the stress', function() {
// describe('of opening and closing ports', function() {
// it("doesn't leak memory", function(done) {
// var hd = new memwatch.HeapDiff();
// var port = new serialPort.SerialPort(testPort, {}, false);
// var port = new SerialPort(testPort, {}, false);

// memwatch.on('leak', function(info) {
// // fs.appendFile('leak.log', util.inspect(info));
Expand Down
5 changes: 2 additions & 3 deletions test/integration-lite.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
// These tests require an empty serialport to exist. Nothing needs to respond on the other end.

var assert = require('chai').assert;
var serialPort = require('../');
var SerialPort = serialPort.SerialPort;
var SerialPort = require('../');

var platform;
switch (process.platform) {
Expand Down Expand Up @@ -39,7 +38,7 @@ describe('SerialPort light integration', function() {
});

it('.list', function(done) {
serialPort.list(done);
SerialPort.list(done);
});

// Be careful to close the ports when you're done with them
Expand Down
Loading

0 comments on commit c645996

Please sign in to comment.