|
|
|
@ -70,6 +70,9 @@ function handleError(call, error) { |
|
|
|
|
status.details = error.details; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (error.hasOwnProperty('metadata')) { |
|
|
|
|
status.metadata = error.metadata; |
|
|
|
|
} |
|
|
|
|
var error_batch = {}; |
|
|
|
|
error_batch[grpc.opType.SEND_STATUS_FROM_SERVER] = status; |
|
|
|
|
call.startBatch(error_batch, function(){}); |
|
|
|
@ -102,15 +105,20 @@ function waitForCancel(call, emitter) { |
|
|
|
|
* @param {*} value The value to respond with |
|
|
|
|
* @param {function(*):Buffer=} serialize Serialization function for the |
|
|
|
|
* response |
|
|
|
|
* @param {Object=} metadata Optional trailing metadata to send with status |
|
|
|
|
*/ |
|
|
|
|
function sendUnaryResponse(call, value, serialize) { |
|
|
|
|
function sendUnaryResponse(call, value, serialize, metadata) { |
|
|
|
|
var end_batch = {}; |
|
|
|
|
end_batch[grpc.opType.SEND_MESSAGE] = serialize(value); |
|
|
|
|
end_batch[grpc.opType.SEND_STATUS_FROM_SERVER] = { |
|
|
|
|
var status = { |
|
|
|
|
code: grpc.status.OK, |
|
|
|
|
details: 'OK', |
|
|
|
|
metadata: {} |
|
|
|
|
}; |
|
|
|
|
if (metadata) { |
|
|
|
|
status.metadata = metadata; |
|
|
|
|
} |
|
|
|
|
end_batch[grpc.opType.SEND_MESSAGE] = serialize(value); |
|
|
|
|
end_batch[grpc.opType.SEND_STATUS_FROM_SERVER] = status; |
|
|
|
|
call.startBatch(end_batch, function (){}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -143,6 +151,7 @@ function setUpWritable(stream, serialize) { |
|
|
|
|
function setStatus(err) { |
|
|
|
|
var code = grpc.status.INTERNAL; |
|
|
|
|
var details = 'Unknown Error'; |
|
|
|
|
var metadata = {}; |
|
|
|
|
if (err.hasOwnProperty('message')) { |
|
|
|
|
details = err.message; |
|
|
|
|
} |
|
|
|
@ -152,7 +161,10 @@ function setUpWritable(stream, serialize) { |
|
|
|
|
details = err.details; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
stream.status = {code: code, details: details, metadata: {}}; |
|
|
|
|
if (err.hasOwnProperty('metadata')) { |
|
|
|
|
metadata = err.metadata; |
|
|
|
|
} |
|
|
|
|
stream.status = {code: code, details: details, metadata: metadata}; |
|
|
|
|
} |
|
|
|
|
/** |
|
|
|
|
* Terminate the call. This includes indicating that reads are done, draining |
|
|
|
@ -166,6 +178,17 @@ function setUpWritable(stream, serialize) { |
|
|
|
|
stream.end(); |
|
|
|
|
} |
|
|
|
|
stream.on('error', terminateCall); |
|
|
|
|
/** |
|
|
|
|
* Override of Writable#end method that allows for sending metadata with a |
|
|
|
|
* success status. |
|
|
|
|
* @param {Object=} metadata Metadata to send with the status |
|
|
|
|
*/ |
|
|
|
|
stream.end = function(metadata) { |
|
|
|
|
if (metadata) { |
|
|
|
|
stream.status.metadata = metadata; |
|
|
|
|
} |
|
|
|
|
Writable.prototype.end.call(this); |
|
|
|
|
}; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
@ -335,11 +358,13 @@ function handleUnary(call, handler, metadata) { |
|
|
|
|
if (emitter.cancelled) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
handler.func(emitter, function sendUnaryData(err, value) { |
|
|
|
|
handler.func(emitter, function sendUnaryData(err, value, trailer) { |
|
|
|
|
if (err) { |
|
|
|
|
err.metadata = trailer; |
|
|
|
|
handleError(call, err); |
|
|
|
|
} else { |
|
|
|
|
sendUnaryResponse(call, value, handler.serialize, trailer); |
|
|
|
|
} |
|
|
|
|
sendUnaryResponse(call, value, handler.serialize); |
|
|
|
|
}); |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
@ -378,12 +403,14 @@ function handleClientStreaming(call, handler, metadata) { |
|
|
|
|
var metadata_batch = {}; |
|
|
|
|
metadata_batch[grpc.opType.SEND_INITIAL_METADATA] = metadata; |
|
|
|
|
call.startBatch(metadata_batch, function() {}); |
|
|
|
|
handler.func(stream, function(err, value) { |
|
|
|
|
handler.func(stream, function(err, value, trailer) { |
|
|
|
|
stream.terminate(); |
|
|
|
|
if (err) { |
|
|
|
|
err.metadata = trailer; |
|
|
|
|
handleError(call, err); |
|
|
|
|
} else { |
|
|
|
|
sendUnaryResponse(call, value, handler.serialize, trailer); |
|
|
|
|
} |
|
|
|
|
sendUnaryResponse(call, value, handler.serialize); |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|