Comparing version
25
admin.js
"use strict"; | ||
var packet = require('gearman-packet'); | ||
var AbraxasError = require('./errors'); | ||
@@ -28,5 +29,3 @@ var getTableQueue = []; | ||
gearman.packets.removeListener('block-complete',completeHandler); | ||
var error = new Error(result.message); | ||
error.name = result.code; | ||
task.acceptError(error); | ||
task.acceptError(new AbraxasError.Server(result.code,result.message)); | ||
callNextQueued(); | ||
@@ -71,7 +70,3 @@ }); | ||
packets.unacceptSerial(event, success); | ||
streamToBuffer(data.body,function(err,body) { | ||
var error = new Error(err ? err : body.toString()); | ||
error.name = data.args['errorcode']; | ||
callback(error); | ||
}); | ||
packets.constructError(data, callback); | ||
} | ||
@@ -85,10 +80,8 @@ packets.acceptSerial(event, success); | ||
return function (err,value) { | ||
if (err) { | ||
var error = new Error(err.message); | ||
error.name = err.code; | ||
task.acceptError(error); | ||
} | ||
else { | ||
task.acceptResult(valuehandler ? valuehandler(value) : null); | ||
} | ||
if (err) { | ||
task.acceptError(new AbraxasError.Server(err.code,err.message)); | ||
} | ||
else { | ||
task.acceptResult(valuehandler ? valuehandler(value) : null); | ||
} | ||
} | ||
@@ -95,0 +88,0 @@ } |
@@ -5,4 +5,5 @@ "use strict"; | ||
var streamToBuffer = require('./stream-to-buffer'); | ||
var AbraxasError = require('./errors'); | ||
exports.getStatus = function (jobid,callback) { | ||
var getStatus = exports.getStatus = function (jobid,callback) { | ||
var self = this; | ||
@@ -12,3 +13,6 @@ | ||
self.packets.acceptByJobOnce('STATUS_RES', jobid, function (data) { | ||
var trace = AbraxasError.trace(getStatus); | ||
self.packets.acceptByJobOnce('STATUS_RES', jobid, function (error,data) { | ||
if (error) return task.acceptError(trace.withError(error)); | ||
var status = {}; | ||
@@ -28,3 +32,3 @@ status.known = Number(data.args.known); | ||
exports.submitJob = function (func,options,data,callback) { | ||
var submitJob = exports.submitJob = function (func,options,data,callback) { | ||
if (callback == null && typeof data == 'function') { | ||
@@ -44,3 +48,3 @@ callback = data; | ||
var task = this.newTask(callback,options); | ||
var trace = new Error(); | ||
var trace = AbraxasError.trace(submitJob); | ||
var self = this; | ||
@@ -55,3 +59,3 @@ var packets = this.packets; | ||
packets.acceptSerialWithError('JOB_CREATED', function (error,data) { | ||
if (error) return task.acceptError(error); | ||
if (error) return task.acceptError(trace.withError(error)); | ||
self.handleJobResult(task,func,trace,packets,data); | ||
@@ -66,3 +70,3 @@ }); | ||
exports.submitJobBg = function (func,options,data,callback) { | ||
var submitJobBg = exports.submitJobBg = function (func,options,data,callback) { | ||
if (callback == null && typeof data == 'function') { | ||
@@ -84,2 +88,3 @@ callback = data; | ||
options.accept = { encoding: 'utf8' }; | ||
var trace = AbraxasError.trace(submitJobBg); | ||
var task = this.newTask(callback, options); | ||
@@ -92,3 +97,3 @@ task.prepareBody(data, function(data) { | ||
packets.acceptSerialWithError('JOB_CREATED', function (error,data) { | ||
if (error) return task.acceptError(error); | ||
if (error) return task.acceptError(trace.withError(error)); | ||
task.acceptResult(data.args['job']); | ||
@@ -103,3 +108,3 @@ }); | ||
exports.submitJobAt = function (func,time,options,data,callback) { | ||
var submitJobAt = exports.submitJobAt = function (func,time,options,data,callback) { | ||
if (callback == null && typeof data == 'function') { | ||
@@ -121,2 +126,3 @@ callback = data; | ||
options.accept = { encoding: 'utf8' }; | ||
var trace = AbraxasError.trace(submitJobAt); | ||
var task = this.newTask(callback, options); | ||
@@ -128,3 +134,3 @@ task.prepareBody(data, function(data) { | ||
packets.acceptSerialWithError('JOB_CREATED', function (error,data) { | ||
if (error) return task.acceptError(error); | ||
if (error) return task.acceptError(trace.withError(error)); | ||
task.acceptResult(data.args['job']); | ||
@@ -138,3 +144,3 @@ }); | ||
exports.submitJobSched = function (func,time,options,data,callback) { | ||
var submitJobSched = exports.submitJobSched = function (func,time,options,data,callback) { | ||
if (callback == null && typeof data == 'function') { | ||
@@ -156,2 +162,3 @@ callback = data; | ||
options.accept = { encoding: 'utf8' }; | ||
var trace = AbraxasError.trace(submitJobSched); | ||
var task = this.newTask(callback, options); | ||
@@ -167,3 +174,3 @@ task.prepareBody(data, function(data) { | ||
packets.acceptSerialWithError('JOB_CREATED', function (error,data) { | ||
if (error) return task.acceptError(error); | ||
if (error) return task.acceptError(trace.withError(error)); | ||
task.acceptResult(data.args['job']); | ||
@@ -201,5 +208,11 @@ }); | ||
streamToBuffer(data.body,function(err, body) { | ||
var lastWarning = err ? err : body.toString(); | ||
task.emit('warn',lastWarning); | ||
return lastWarning; | ||
if (err) { | ||
cancel(); | ||
task.acceptError(trace.withError(new AbraxasError.Receive(err.message))); | ||
task.end(); | ||
} | ||
else { | ||
lastWarning = body.toString(); | ||
task.emit('warn',lastWarning); | ||
} | ||
}); | ||
@@ -213,8 +226,8 @@ }); | ||
if (lastWarning == null) { | ||
task.emit('error', new Error('Job '+jobid+' failed')); | ||
task.end(); | ||
task.acceptError(trace.withError(new AbraxasError.JobFail(func,jobid))); | ||
} | ||
else { | ||
task.emit('error',new Error(lastWarning)); | ||
task.acceptError(trace.withError(new AbraxasError.JobException(func,jobid,lastWarning))); | ||
} | ||
task.end(); | ||
}); | ||
@@ -224,6 +237,8 @@ packets.acceptByJob('WORK_EXCEPTION', jobid, function (data) { | ||
streamToBuffer(data.body,function (err, body) { | ||
var error = new Error(err ? err : body.toString()); | ||
error.name = func; | ||
error.jobid = jobid; | ||
task.emit('error',error); | ||
if (err) { | ||
task.acceptError(trace.withError(new AbraxasError.Receive(err.message))); | ||
} | ||
else { | ||
task.acceptError(trace.withError(new AbraxasError.JobException(func,jobid,body.toString()))); | ||
} | ||
task.end(); | ||
@@ -234,4 +249,8 @@ }); | ||
cancel(); | ||
data.body.on('error',function (err) { | ||
task.acceptError(trace.withError(new AbraxasError.Receive(err))); | ||
task.end(); | ||
}); | ||
data.body.pipe(out); | ||
}); | ||
} |
@@ -10,2 +10,3 @@ "use strict"; | ||
var AbraxasSocket = require('./socket'); | ||
var AbraxasError = require('./errors'); | ||
@@ -22,5 +23,8 @@ var AbraxasClient = module.exports = function (options) { | ||
streamToBuffer(data.body,function(err, body) { | ||
var error = new Error(err ? err : body.toString()); | ||
error.name = data.args['errorcode']; | ||
self.emitError(error); | ||
if (err) { | ||
self.emitError(new AbraxasError.Receive()); | ||
} | ||
else { | ||
self.emitError(new AbraxasError.Server(data.args.errorcode,body)); | ||
} | ||
}); | ||
@@ -40,12 +44,10 @@ }); | ||
this.socket.write({kind:'request',type:packet.types['OPTION_REQ'],args:{option:'streaming'}}); | ||
var trace = new Error(); | ||
var trace = AbraxasError.trace(AbraxasClient); | ||
this.packets.acceptSerialWithError('OPTION_RES', function (err,data) { | ||
if (err) { | ||
if (err.name == 'UNKNOWN_OPTION') { | ||
trace.name = err.name; | ||
trace.message = 'Server does not support option "streaming"'; | ||
self.emitError(trace); | ||
if (err.code == 'UNKNOWN_OPTION') { | ||
self.emitError(trace.withError(new AbraxasError.NoStreaming)); | ||
} | ||
else { | ||
self.emitError(err); | ||
self.emitError(trace.withError(err)); | ||
} | ||
@@ -89,4 +91,11 @@ return; | ||
var self = this; | ||
task.on('end',function(){ self.unref() }); | ||
var connectionClose = function (had_error){ | ||
task.acceptError(new AbraxasError.Socket('connection '+(had_error?'error':'closed'))); | ||
}; | ||
this.connection.once('close', connectionClose); | ||
task.once('close',function(){ | ||
self.unref(); | ||
self.connection.removeListener('close', connectionClose); | ||
}); | ||
return task; | ||
} |
2
e.js
@@ -27,3 +27,3 @@ var Gearman = require('./index.js'); | ||
cv.begin(); | ||
var cl = Gearman.Client.connect({ defaultEncoding:'utf8', debug: true }); | ||
var cl = Gearman.Client.connect({ defaultEncoding:'utf8', debug: true, packetDump: true }); | ||
// var cl = client; | ||
@@ -30,0 +30,0 @@ cl.submitJob('toUpper', {encoding: 'utf8',uniqueid:'test'+v}, 'test string '+v,function(err,result) { |
"use strict"; | ||
exports.Server = require('./server'); | ||
exports.Client = require('./client'); | ||
exports.Error = require('./errors'); |
@@ -12,11 +12,12 @@ { | ||
"author": "Rebecca Turner <me@re-becca.org> (http://re-becca.org)", | ||
"version": "0.3.1", | ||
"version": "0.4.0", | ||
"dependencies": { | ||
"bluebird": "^2.1.3", | ||
"concat-stream": "^1.4.6", | ||
"duplex-combination": "^1.1.1", | ||
"gearman-packet": "^1.0.0", | ||
"through2": "^0.4.1", | ||
"util-extend": "^1.0.1", | ||
"concat-stream": "^1.4.6", | ||
"bluebird": "^2.1.3", | ||
"duplex-combination": "^1.0.1", | ||
"shallow-copy": "0.0.1" | ||
"shallow-copy": "^0.0.1", | ||
"standard-error": "^1.1.0", | ||
"through2": "^0.5.1", | ||
"util-extend": "^1.0.1" | ||
}, | ||
@@ -26,3 +27,3 @@ "main": "index.js", | ||
"scripts": { | ||
"test": "tape $(find test -name '*.js')" | ||
"test": "tape $(find test -name '[^.]*.js')" | ||
}, | ||
@@ -34,3 +35,3 @@ "repository": { | ||
"devDependencies": { | ||
"tape": "^1.0.4" | ||
"tape": "^2.13.4" | ||
}, | ||
@@ -37,0 +38,0 @@ "directories": { |
@@ -5,2 +5,3 @@ "use strict"; | ||
var streamToBuffer = require('./stream-to-buffer'); | ||
var AbraxasError = require('./errors'); | ||
@@ -65,2 +66,13 @@ var PacketHandler = module.exports = function () { | ||
PacketHandler.prototype.constructError = function (data,callback) { | ||
streamToBuffer(data.body,function(err,body) { | ||
if (err) { | ||
callback(new AbraxasError.Receive(err)); | ||
} | ||
else { | ||
callback(new AbraxasError.Server(data.args.errorcode,body)); | ||
} | ||
}); | ||
} | ||
PacketHandler.prototype.acceptSerialWithError = function (event, callback) { | ||
@@ -74,7 +86,3 @@ var self = this; | ||
self.unacceptSerial(event, success); | ||
streamToBuffer(data.body,function(err,body) { | ||
var error = new Error(err ? err : body.toString()); | ||
error.name = data.args['errorcode']; | ||
callback(error); | ||
}); | ||
self.constructError(data, callback); | ||
} | ||
@@ -112,6 +120,13 @@ this.acceptSerial(event, success); | ||
var self = this; | ||
this.acceptByJob( event, id, function(packet) { | ||
var success = function(packet) { | ||
self.unacceptByJob(event, id); | ||
callback(packet); | ||
}); | ||
self.unacceptSerial('ERROR',failure); | ||
callback(null,packet); | ||
} | ||
var failure = function (packet) { | ||
self.unacceptByJob(event, id); | ||
self.constructError(packet, callback); | ||
} | ||
this.acceptByJob(event, id, success); | ||
this.acceptSerial('ERROR', failure); | ||
} |
@@ -176,11 +176,5 @@ "use strict"; | ||
ServerConnection.prototype.write = function (packet,callback) { | ||
if (this.socket) { | ||
var flushed = this.socket.write(packet); | ||
if (!callback) return; | ||
if (flushed) { callback() } else { this.socket.once('drain', callback) } | ||
} | ||
else { | ||
console.error("Disconnected, couldn't write packet", new Error().stack); | ||
if (callback) callback(); | ||
} | ||
var flushed = this.socket.write(packet); | ||
if (!callback) return; | ||
if (flushed) { callback() } else { this.socket.once('drain', callback) } | ||
} | ||
@@ -187,0 +181,0 @@ |
@@ -39,2 +39,3 @@ "use strict"; | ||
if (!options.port) options.port = 4730; | ||
if (!options.host) options.host = 'localhost'; | ||
server.listen(options.port, options.host, options.backlog, callback); | ||
@@ -46,2 +47,6 @@ } | ||
Server.prototype.shutdown = function () { | ||
this.socket.close(); | ||
} | ||
Server.prototype.acceptConnection = function (socket) { | ||
@@ -54,11 +59,10 @@ var id = ++ this.clientMaxId; | ||
var client = this.clients[id] = new ServerConnection(this,options); | ||
client.on('error',function(e) { | ||
console.error(e); | ||
client.destroy(); | ||
}); | ||
client.on('error',function(e) { client.destroy() }); | ||
var self = this; | ||
['add-worker', 'remove-worker', 'get-status', 'submit-job', 'grab-job', | ||
['add-worker', 'remove-worker', 'remove-all-workers', 'get-status', 'submit-job', 'grab-job', | ||
'work-complete', 'work-data', 'work-warning', 'work-exception', | ||
'update-status'].forEach(function(event) { | ||
var methodname = event.replace(/-([a-z])/,function(match,p1){ return p1.toUpperCase() }); | ||
var methodname = event.replace(/-([a-z])/g,function(match,p1){ return p1.toUpperCase() }); | ||
var method = self[methodname]; | ||
@@ -65,0 +69,0 @@ client.on(event, function () { method.apply(self,arguments) }); |
@@ -9,2 +9,3 @@ "use strict"; | ||
var debugPacket = require('./debug-packet'); | ||
var AbraxasError = require('./errors'); | ||
@@ -53,3 +54,8 @@ var maxId = 0; | ||
} | ||
this.connection.on('error', function(error){ self.emitError(new Error("Socket error: "+error)) }); | ||
var connectionError = function(error){ self.emitError(new AbraxasError.Connect(error)) } | ||
this.connection.once('error', connectionError); | ||
this.connection.on('connect', function () { | ||
self.connection.removeListener('error', connectionError); | ||
self.connection.on('error', function (error){ self.emitError(new AbraxasError.Socket(error)) }); | ||
}); | ||
this.connection.on('end', function(){ self.emit('disconnect') }); | ||
@@ -76,3 +82,3 @@ | ||
input = input.pipe(new packet.Parser()); | ||
input.on('error', function(error){ self.emitError(new Error("Parser error: "+error)) }); | ||
input.on('error', function(error){ self.emitError(new AbraxasError.Parser(error)) }); | ||
var emitter = new packet.Emitter(); | ||
@@ -82,3 +88,3 @@ this.socket = output ? output : emitter; | ||
output = emitter; | ||
output.on('error', function(error){ self.emitError(new Error("Emitter error: "+error)) }); | ||
output.on('error', function(error){ self.emitError(new AbraxasError.Emitter(error)) }); | ||
@@ -117,6 +123,4 @@ if (this.options.packetDump) input = observe(input,function(D){ self.emitRead(D) }); | ||
AbraxasSocket.prototype.emitError = function (error) { | ||
if (events.EventEmitter.listenerCount(this,'error')) return this.emit('error',error); | ||
throw error; | ||
this.emit('error',error); | ||
} | ||
@@ -123,0 +127,0 @@ |
@@ -28,6 +28,12 @@ "use strict"; | ||
if (options.nobody) transmit.end(); | ||
var self = this; | ||
this.on('end', function () { self.emit('close') }); | ||
} | ||
util.inherits(ClientTask, Task); | ||
// Emits error, warn and status events | ||
ClientTask.prototype.end = function () { | ||
Task.prototype.end.call(this); | ||
this.emit('close'); | ||
} | ||
@@ -40,12 +46,12 @@ ClientTask.prototype.acceptError = function (error) { | ||
if (result == null) { | ||
this._reader.end(); | ||
this.reader.end(); | ||
} | ||
else if (result.pipe) { | ||
result.pipe(this._reader); | ||
result.pipe(this.reader); | ||
} | ||
else { | ||
this._reader._writableState.objectMode = true; | ||
this._reader._readableState.objectMode = true; | ||
this._reader.write(result, this.options.accept && this.options.accept.encoding ? this.options.accept.encoding : this.options.encoding ); | ||
this._reader.end(); | ||
this.reader._writableState.objectMode = true; | ||
this.reader._readableState.objectMode = true; | ||
this.reader.write(result, this.options.accept && this.options.accept.encoding ? this.options.accept.encoding : this.options.encoding ); | ||
this.reader.end(); | ||
} | ||
@@ -57,7 +63,7 @@ } | ||
if (this.options.bodySize) { | ||
this._writer.length = this.options.bodySize; | ||
callback(this._writer); | ||
this.writer.length = this.options.bodySize; | ||
callback(this.writer); | ||
} | ||
else { | ||
this._writer.pipe(concat(function(body) { callback(body) })); | ||
this.writer.pipe(concat(function(body) { callback(body) })); | ||
} | ||
@@ -64,0 +70,0 @@ } |
"use strict"; | ||
var Promise = require('bluebird'); | ||
var concat = require('concat-stream'); | ||
var stream = require('stream'); | ||
@@ -20,10 +22,21 @@ var util = require('util'); | ||
} | ||
this.outbound = new stream.PassThrough(options.response); | ||
var outbound = new stream.PassThrough(options.response); | ||
if (options.encoding && (!options.response || !options.response.encoding)) { | ||
this.outbound.setEncoding(options.encoding); | ||
outbound.setEncoding(options.encoding); | ||
} | ||
Task.call(this,payload,this.outbound,options); | ||
Task.call(this,payload,outbound,options); | ||
} | ||
util.inherits(WorkerTask, Task); | ||
WorkerTask.prototype._makePromise = function () { | ||
var self = this; | ||
this.promise = new Promise(function(resolve,reject) { | ||
if (self.listeners('error')==0) { | ||
self.reader.removeAllListeners('error'); | ||
} | ||
self.pipe(concat(function(body) { resolve(body) })); | ||
self.reader.once('error', function (err) { reject(err) }); | ||
}); | ||
} | ||
WorkerTask.prototype.end = function (data) { | ||
@@ -35,6 +48,19 @@ if (this.lastChunk != null) return; | ||
WorkerTask.prototype.warn = function (msg) { | ||
if (!this.client.connected) return; | ||
this.client.socket.write({kind:'request',type:packet.types['WORK_WARNING'], args:{job:this.jobid}, body:msg}); | ||
} | ||
WorkerTask.prototype.status = function (percent) { | ||
if (!this.client.connected) return; | ||
this.client.socket.write({kind:'request',type:packet.types['WORK_STATUS'], args:{job:this.jobid, complete:percent*100, total: 100}}); | ||
} | ||
WorkerTask.prototype.error = function (err) { | ||
if (!this.client.connected) return; | ||
if (this.client.feature.exceptions) { | ||
this.client.socket.write({kind:'request',type:packet.types['WORK_EXCEPTION'], args:{job:this.jobid}, body:err}); | ||
} | ||
else { | ||
this.client.socket.write({kind:'request',type:packet.types['WORK_WARNING'], args:{job:this.jobid}, body:err}); | ||
this.client.socket.write({kind:'request',type:packet.types['WORK_FAIL'], args:{job:this.jobid}}); | ||
} | ||
this.client.endWork(this.jobid); | ||
} |
@@ -8,3 +8,3 @@ "use strict"; | ||
var Task = module.exports = function Task(reader,writer,options) { | ||
DuplexCombination.call(this,reader,writer, options); | ||
DuplexCombination.call(this,reader,writer,options); | ||
} | ||
@@ -17,3 +17,3 @@ util.inherits(Task, DuplexCombination); | ||
self.pipe(concat(function(body) { resolve(body) })); | ||
self.on('error', function (err) { reject(err) }); | ||
self.once('error', function (err) { reject(err) }); | ||
}); | ||
@@ -20,0 +20,0 @@ } |
@@ -17,3 +17,3 @@ "use strict"; | ||
resultValue = value; | ||
}); | ||
}, {encoding: 'utf8'}); | ||
task.acceptResult(useStream ? streamify([data]) : data); | ||
@@ -31,3 +31,3 @@ setImmediate(function() { | ||
var resultValue; | ||
var task = new ClientTask(); | ||
var task = new ClientTask(null,{encoding: 'utf8'}); | ||
task.acceptResult(useStream ? streamify([data]) : data); | ||
@@ -37,3 +37,3 @@ task.then(function (value) { resultValue = value }, function (error) { resultError = error }); | ||
t.is(resultError, void 0, 'No error'); | ||
t.is(resultValue.toString(), data, 'Passed through data'); | ||
t.is(resultValue, data, 'Passed through data'); | ||
}); | ||
@@ -47,3 +47,3 @@ } | ||
var resultValue; | ||
var task = new ClientTask(); | ||
var task = new ClientTask(null,{encoding: 'utf8'}); | ||
task.acceptResult(useStream ? streamify([data]) : data); | ||
@@ -54,3 +54,3 @@ task.pipe(concat(function(value) { resultValue = value })); | ||
t.is(resultError, void 0, 'No error'); | ||
t.is(resultValue.toString(), data, 'Passed through data'); | ||
t.is(resultValue, data, 'Passed through data'); | ||
}); | ||
@@ -72,5 +72,5 @@ } | ||
var did = {}; | ||
task._writer = {pipe: function () { did.pipe = true }} | ||
task.writer = {pipe: function () { did.pipe = true }} | ||
task.prepareBody(body,function (value) { | ||
if (value === task._writer) { | ||
if (value === task.writer) { | ||
did.cbWithWriter = true; | ||
@@ -77,0 +77,0 @@ } |
@@ -6,5 +6,2 @@ Server | ||
* Disable WORK_DATA packets when not in streaming mode (buffer for | ||
WORK_COMPLETE instead). Add data command to explicitly send WORK_DATA | ||
packets even in streaming mode. | ||
* Spooling jobs to disk as they come in, rather then memory (StreamReplay) | ||
@@ -17,2 +14,8 @@ This should be plugable, with at least memory and disk backends. | ||
Worker | ||
* Disable WORK_DATA packets when not in streaming mode (buffer for | ||
WORK_COMPLETE instead). Add data command to explicitly send WORK_DATA | ||
packets even in streaming mode. | ||
General | ||
@@ -19,0 +22,0 @@ |
@@ -144,3 +144,3 @@ "use strict"; | ||
task.outbound.on('data', function (data) { | ||
task.writer.on('data', function (data) { | ||
if (!self.connected) return; | ||
@@ -150,17 +150,3 @@ self.socket.write({kind:'request',type:packet.types['WORK_DATA'], args:{job:jobid}, body:data}); | ||
var sendException = function (msg) { | ||
if (!self.connected) return; | ||
if (self.exceptions) { | ||
self.socket.write({kind:'request',type:packet.types['WORK_EXCEPTION'], args:{job:jobid}, body:msg}); | ||
} | ||
else { | ||
self.socket.write({kind:'request',type:packet.types['WORK_WARNING'], args:{job:jobid}, body:msg}); | ||
self.socket.write({kind:'request',type:packet.types['WORK_FAIL'], args:{job:jobid}}); | ||
} | ||
self.endWork(jobid); | ||
} | ||
task.outbound.on('error', sendException); | ||
task.outbound.on('end', function () { | ||
task.writer.on('end', function () { | ||
if (self.connected) { | ||
@@ -178,9 +164,9 @@ var end = {kind:'request',type:packet.types['WORK_COMPLETE'], args:{job:jobid}}; | ||
value.pipe(task); | ||
value.on('error', sendException); | ||
value.on('error', function (err) { task.error(err) }); | ||
} | ||
else if (value && value.then) { | ||
value.then(handleReturnValue, sendException); | ||
value.then(handleReturnValue, function (err) { task.error(err) }); | ||
} | ||
else if (value instanceof Error) { | ||
sendException(value); | ||
task.error(value); | ||
} | ||
@@ -195,4 +181,4 @@ else if (value != null) { | ||
catch (error) { | ||
sendException(error); | ||
task.error(error); | ||
} | ||
} |
123579
5.54%51
4.08%2576
13.83%8
14.29%4
33.33%+ Added
+ Added
+ Added
+ Added
- Removed
- Removed
- Removed
Updated
Updated
Updated