Permalink
Browse files

Good error handling and test running

  • Loading branch information...
1 parent 0aa798d commit 22a9fceb2931837c0b9668f8c8cb74aa4de0c9b7 @felixge felixge committed May 5, 2012
View
@@ -0,0 +1,4 @@
+test:
+ node test/run.js
+
+.PHONY: test
View
@@ -1,9 +1,14 @@
-var Net = require('net');
-var Config = require('./Config');
-var Protocol = require('./protocol/Protocol');
+var Net = require('net');
+var Config = require('./Config');
+var Protocol = require('./protocol/Protocol');
+var EventEmitter = require('events').EventEmitter;
+var Util = require('util');
module.exports = Connection;
+Util.inherits(Connection, EventEmitter);
function Connection(options) {
+ EventEmitter.call(this);
+
this.config = new Config(options.config);
this._socket = options.socket;
@@ -21,6 +26,7 @@ Connection.prototype.connect = function(cb) {
this._protocol.handshake(this.config, cb);
this._socket.on('error', this._handleNetworkError.bind(this));
+ this._protocol.on('error', this._handleProtocolError.bind(this));
};
Connection.prototype.query = function(sql, cb) {
@@ -36,3 +42,7 @@ Connection.prototype.end = function() {
Connection.prototype._handleNetworkError = function(err) {
this._protocol.fatalError(err);
};
+
+Connection.prototype._handleProtocolError = function(err) {
+ this.emit('error', err);
+};
@@ -93,8 +93,8 @@ Protocol.prototype._executeSequence = function(sequence) {
var self = this;
sequence
- .on('fatalError', function(err) {
- self.fatalError(err);
+ .on('error', function(err) {
+ self._handleSequenceError(sequence, err);
})
.on('data', function(buffer) {
self.emit('data', buffer);
@@ -115,14 +115,34 @@ Protocol.prototype._dequeue = function() {
}
};
+Protocol.prototype._handleSequenceError = function(sequence, err) {
+ var bubbleUp = (sequence.hasCallback())
+ ? false
+ : err.fatal && !this._hasPendingCallbacks();
+
+ if (bubbleUp) {
+ this.emit('error', err);
+ }
+
+ if (err.fatal) {
+ this.fatalError(err);
+ }
+};
+
+Protocol.prototype._hasPendingCallbacks = function() {
+ return this._queue.some(function(sequence) {
+ return sequence.hasCallback();
+ });
+};
+
Protocol.prototype.fatalError = function(err) {
err.fatal = true;
var pendingSequences = this._queue;
this._queue = [];
pendingSequences.forEach(function(sequence) {
- sequence.end(err);
+ sequence.invokeCallback(err);
});
};
@@ -21,6 +21,10 @@ Sequence.determinePacket = function(byte) {
}
};
+Sequence.prototype.hasCallback = function() {
+ return Boolean(this._callback);
+};
+
Sequence.packetToError = function(packet) {
var err = new Error(packet.message);
err.code = ErrorConstants[packet.errno] || 'UNKNOWN_CODE_PLEASE_REPORT';
@@ -51,18 +55,21 @@ Sequence.prototype._incrementNextPacketNumber = function() {
this._nextPacketNumber = (this._nextPacketNumber + 1) % 256;
};
+Sequence.prototype.invokeCallback = function() {
+ if (this._callback) {
+ this._callback.apply(this, arguments);
+ }
+};
+
Sequence.prototype.end = function(err) {
if (this._callback) {
this._callback.apply(this, arguments);
- } else if (err) {
- this.emit('error', err);
}
this.emit('end');
- if (err.fatal) {
- this.emit('fatalError', err);
- return;
+ if (err) {
+ this.emit('error', err);
}
};
@@ -0,0 +1,16 @@
+var common = require('../common');
+var connection = common.createConnection({password: common.bogusPassword});
+var assert = require('assert');
+
+connection.connect();
+connection.query('SELECT 1');
+
+var err;
+connection.on('error', function(_err) {
+ err = _err;
+});
+
+process.on('exit', function() {
+ assert.equal(err.code, 'ER_ACCESS_DENIED_ERROR');
+ assert.equal(err.fatal, true);
+});
View
@@ -0,0 +1 @@
+require('urun')(__dirname)

0 comments on commit 22a9fce

Please sign in to comment.