diff --git a/net/js/package.json b/net/js/package.json
index 460025828764649f516ec005fddae1c3c6445bea..52bbcc4bd473d4fd7913d43b3c2fa97ea76138e8 100644
--- a/net/js/package.json
+++ b/net/js/package.json
@@ -15,6 +15,7 @@
     "ws": "^6.2.1"
   },
   "devDependencies": {
+    "chai": "^4.2.0",
     "mocha": "^6.0.2"
   }
 }
diff --git a/net/js/src/socket.js b/net/js/src/socket.js
index d051f87637fc060fdbdbdfded37b73c1d89be2ad..22b70d44c9adfd6dff926286369ea1d751738a05 100644
--- a/net/js/src/socket.js
+++ b/net/js/src/socket.js
@@ -13,7 +13,10 @@ function Socket(uri) {
 		'close': []
 	};
 	
+	this.handshake_ = false;
+	this.lasterr_ = null;
 	this.connected_ = false;
+	this.valid_ = false;
 	this.buffer_ = new Buffer(0);
 
 	if (t == "string") {
@@ -23,24 +26,49 @@ function Socket(uri) {
 	}
 }
 
+Socket.ERROR_BADPROTOCOL = 0x01;
+Socket.ERROR_BADHOST = 0x02;
+Socket.ERROR_BADHANDSHAKE = 0x03;
+Socket.ERROR_MALFORMEDURI = 0x04;
+
+Socket.prototype.isValid = function() {
+	return this.valid_;
+}
+
+/**
+ * Construct the correct kind of socket connection from a URI.
+ */
 Socket.prototype._fromURI = function(uri) {
 	let uriobj = urijs.parse(uri);
-	
 	this.uri_ = uri;
 	this.scheme_ = uriobj.scheme;
 	
+	// Could not parse uri so report error
+	if (uriobj.scheme === undefined || uriobj.host === undefined) {
+		this.lasterr_ = Socket.ERROR_MALFORMEDURI;
+		this.dispatch('error', [this.lasterr_]);
+		return;
+	}
+	
+	// Websocket protocol
 	if (this.scheme_ == "ws") {
+		// Detect if in browser or not, choose correct websocket object
 		if (typeof WebSocket == "undefined") {
+			// Nodejs
 			this.socket_ = new ws(uri);
 		} else {
+			// Browser
 			this.socket_ = new WebSocket(uri);
 		}
 		this._initWebsocket();
+	// TCP
 	} else if (this.scheme_ == "tcp") {
 		this.socket_ = net.connect(uriobj.port, uriobj.host);
 		this._initTCPSocket();
+	// Unrecognised protocol
 	} else {
-		console.error("Invalid URI scheme for socket: ", this.scheme_);
+		this.lasterr_ = Socket.ERROR_BADPROTOCOL;
+		this.dispatch('error', [this.lasterr_]);
 	}
 }
 
@@ -60,7 +88,12 @@ Socket.prototype._fromObject = function(sock) {
 	else if (this.scheme_ == "tcp") this._initTCPSocket();
 }
 
+/**
+ * Setup correct handlers for a websocket connection.
+ */
 Socket.prototype._initWebsocket = function() {
+	this.valid_ = true;
+
 	let dataHandler = (data) => {
 		let size = binary.readUInt32LE(data, 0);
 		let service = binary.readUInt32LE(data, 4);
@@ -80,9 +113,27 @@ Socket.prototype._initWebsocket = function() {
 	} else {
 		this.socket_.on('message', dataHandler);
 	}
+	this.socket_.on('open', () => {
+		this.connected_ = true;
+		this.dispatch('open', []);
+	});
+	this.socket_.on('error', (err) => {
+		this.connected_ = false;
+		this.valid_ = false;
+		switch (err.errno) {
+		case 'ENOTFOUND'	: this.lasterr_ = Socket.ERROR_BADHOST; break;
+		default				: this.lasterr_ = err.errno;
+		}
+		this.dispatch('error', [this.lasterr_]);
+	});
+	this.socket_.on('close', () => {
+		this.dispatch('close', []);
+	});
 }
 
 Socket.prototype._initTCPSocket = function() {
+	this.valid_ = true;
+
 	let dataHandler = (data) => {
 		console.log('Received: ' + data);
 		this.buffer_ = Buffer.concat([this.buffer_, data]);
@@ -111,12 +162,28 @@ Socket.prototype._initTCPSocket = function() {
 		this.connected_ = true;
 		this.dispatch('open', []);
 	});
+	this.socket_.on('error', (err) => {
+		this.connected_ = false;
+		this.valid_ = false;
+		console.log("Sock error: ", err);
+		switch (err.errno) {
+		case 'ENOTFOUND'	: this.lasterr_ = Socket.ERROR_BADHOST; break;
+		default				: this.lasterr_ = err.errno;
+		}
+		this.dispatch('error', [this.lasterr_]);
+	});
+	this.socket_.on('close', () => {
+		this.dispatch('close', []);
+	});
 }
 
 Socket.prototype.isConnected = function() {
 	return this.connected_;
 }
 
+/**
+ * Register event handlers.
+ */
 Socket.prototype.on = function(name, f) {
 	if (typeof name == "string") {
 		if (this.handlers_.hasOwnProperty(name)) {
@@ -124,6 +191,10 @@ Socket.prototype.on = function(name, f) {
 		} else {
 			console.error("Unrecognised handler: ", name);
 		}
+		
+		if (name == "error" && this.lasterr_ != null) {
+			f(this.lasterr_);
+		}
 	} else if (typeof name == "number") {
 		if (this.handlers_[name] === undefined) this.handlers_[name] = [];
 		this.handlers_[name].push(f);
@@ -145,7 +216,11 @@ Socket.prototype.dispatch = function(h, args) {
 }
 
 Socket.prototype.close = function() {
-	this.socket_.destroy();
+	if (this.scheme_ == "ws") {
+		this.socket_.close();
+	} else {
+		this.socket_.destroy();
+	}
 	this.socket_ = null;
 }
 
diff --git a/net/js/test/socket_unit.js b/net/js/test/socket_unit.js
index c7c104d198044e28fcce24600a544863a7d88ffd..a1cc4f78c8a8abe59feb73ee952db84a00842571 100644
--- a/net/js/test/socket_unit.js
+++ b/net/js/test/socket_unit.js
@@ -1,31 +1,110 @@
 const Socket = require('../src/socket.js');
-const assert = require('assert');
+const assert = require('chai').assert;
 const net = require('net');
 const binary = require('bops');
+const WebSocket = require('ws');
 
-describe("Constructing a socket", function() {
+describe("Socket()", function() {
 	let server;
+	let wss;
+	let dobadhandshake = false;
 	
 	beforeEach(() => {
+		dobadhandshake = false;
 		server = net.createServer(socket => {
-			console.log("Client connected");
+			socket.on('error', ()=> {});
+			if (dobadhandshake) {
+				socket.write(Buffer.from([44,55,33,22,23,44,87]));
+			} else {
+				socket.write(Buffer.from([0x12,0x09,0x64,0x53,0x00,0x34,0x99,0x10,3,0,0,0,3,0,0,0,67,67,67,67,67,67]));
+			}
 		});
 		server.listen(9000, 'localhost');
+		
+		wss = new WebSocket.Server({ port: 9001 });
+		wss.on('connection', (ws) => {
+			ws.on('error', ()=> {});
+			if (dobadhandshake) {
+				ws.send(Buffer.from([44,55,33,22,23,44,87]));
+			} else {
+				ws.send(Buffer.from([0x12,0x09,0x64,0x53,0x00,0x34,0x99,0x10,3,0,0,0,3,0,0,0,67,67,67,67,67,67]));
+			}
+		});
 	});
 	
-	it("Connects to a valid tcp uri", function(done) {
-		let sock = new Socket("tcp://localhost:9000");
-		sock.on('open', () => {
-			console.log("OPEN");
-			assert.equal(sock.isConnected(),true);
-			sock.close();
-			done();
+	context("with a valid connection uri and handshake", () => {
+		it("make a tcp connection", function(done) {
+			let sock = new Socket("tcp://localhost:9000");
+			sock.on('open', () => {
+				assert.isOk(sock.isConnected());
+				sock.close();
+				done();
+			});
+		});
+		
+		it("make a websocket connection", function(done) {
+			let sock = new Socket("ws://localhost:9001");
+			sock.on('open', () => {
+				assert.isOk(sock.isConnected());
+				sock.close();
+				done();
+			});
+		});
+	});
+	
+	context("with a valid uri but bad handshake", () => {
+		it("should reject the connection", () => {
+			let diderror = false;
+			dobadhandshake = true;
+			let sock = new Socket("tcp://localhost:9000");
+			sock.on('error', (errno) => {
+				diderror = true;
+				assert.equal(errno, Socket.ERROR_BADHANDSHAKE);
+				assert.isOk(sock.isValid());
+				assert.isNotOk(sock.isConnected());
+			});
+			assert.isOk(diderror);
+		});
+	});
+	
+	context("with an invalid connection uri", () => {
+		it("should give protocol error", () => {
+			let diderror = false;
+			let sock = new Socket("xyz://localhost:9000");
+			sock.on('error', (errno) => {
+				diderror = true;
+				assert.equal(errno, Socket.ERROR_BADPROTOCOL);
+				assert.isNotOk(sock.isValid());
+			});
+			assert.isOk(diderror);
+		});
+		
+		it("should give host error", (done) => {
+			let sock = new Socket("tcp://blah.blah:9000");
+			sock.on('error', (errno) => {
+				assert.equal(errno, Socket.ERROR_BADHOST);
+				assert.isNotOk(sock.isValid());
+				done();
+			});
+		});
+		
+		it("should give a malformed uri error", () => {
+			let diderror = false;
+			let sock = new Socket("helloworld");
+			sock.on('error', (errno) => {
+				diderror = true;
+				assert.equal(errno, Socket.ERROR_MALFORMEDURI);
+				assert.isNotOk(sock.isValid());
+			});
+			assert.isOk(diderror);
 		});
 	});
 	
 	afterEach(() => {
 		server.close(() => { console.log("Closed"); });
 		server.unref();
+		
+		wss.close();
 	});
 });
 
@@ -34,7 +113,6 @@ describe("Receiving messages on a tcp socket", function() {
 	
 	beforeEach(() => {
 		server = net.createServer(socket => {
-			console.log("Client connected");
 			socket.write(Buffer.from([8,0,0,0,44,0,0,0,23,0,0,0]));
 		});
 		server.listen(9001, 'localhost');
@@ -57,3 +135,4 @@ describe("Receiving messages on a tcp socket", function() {
 	});
 });
 
+