Merge pull request #1270 from murgatroid99/unimplemented_message_improvement

Include method name in UNIMPLEMENTED details string
This commit is contained in:
Michael Lumish 2020-02-21 09:37:27 -08:00 committed by GitHub
commit aef71e9e39
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 70 additions and 43 deletions

View File

@ -49,11 +49,15 @@ import { ChannelOptions } from './channel-options';
function noop(): void {} function noop(): void {}
const unimplementedStatusResponse: Partial<ServiceError> = { function getUnimplementedStatusResponse(
methodName: string
): Partial<ServiceError> {
return {
code: Status.UNIMPLEMENTED, code: Status.UNIMPLEMENTED,
details: 'The server does not implement this method', details: `The server does not implement the method ${methodName}`,
metadata: new Metadata(), metadata: new Metadata(),
}; };
}
// tslint:disable:no-any // tslint:disable:no-any
type UntypedUnaryHandler = UnaryHandler<any, any>; type UntypedUnaryHandler = UnaryHandler<any, any>;
@ -66,23 +70,37 @@ export interface UntypedServiceImplementation {
[name: string]: UntypedHandleCall; [name: string]: UntypedHandleCall;
} }
const defaultHandler = { function getDefaultHandler(handlerType: HandlerType, methodName: string) {
unary(call: ServerUnaryCall<any, any>, callback: sendUnaryData<any>): void { const unimplementedStatusResponse = getUnimplementedStatusResponse(
methodName
);
switch (handlerType) {
case 'unary':
return (
call: ServerUnaryCall<any, any>,
callback: sendUnaryData<any>
) => {
callback(unimplementedStatusResponse as ServiceError, null); callback(unimplementedStatusResponse as ServiceError, null);
}, };
clientStream( case 'clientStream':
return (
call: ServerReadableStream<any, any>, call: ServerReadableStream<any, any>,
callback: sendUnaryData<any> callback: sendUnaryData<any>
): void { ) => {
callback(unimplementedStatusResponse as ServiceError, null); callback(unimplementedStatusResponse as ServiceError, null);
},
serverStream(call: ServerWritableStream<any, any>): void {
call.emit('error', unimplementedStatusResponse);
},
bidi(call: ServerDuplexStream<any, any>): void {
call.emit('error', unimplementedStatusResponse);
},
}; };
case 'serverStream':
return (call: ServerWritableStream<any, any>) => {
call.emit('error', unimplementedStatusResponse);
};
case 'bidi':
return (call: ServerDuplexStream<any, any>) => {
call.emit('error', unimplementedStatusResponse);
};
default:
throw new Error(`Invalid handlerType ${handlerType}`);
}
}
// tslint:enable:no-any // tslint:enable:no-any
export class Server { export class Server {
@ -157,7 +175,7 @@ export class Server {
if (implFn !== undefined) { if (implFn !== undefined) {
impl = implFn.bind(implementation); impl = implFn.bind(implementation);
} else { } else {
impl = defaultHandler[methodType]; impl = getDefaultHandler(methodType, name);
} }
const success = this.register( const success = this.register(
@ -353,7 +371,7 @@ export class Server {
const handler = this.handlers.get(path); const handler = this.handlers.get(path);
if (handler === undefined) { if (handler === undefined) {
throw unimplementedStatusResponse; throw getUnimplementedStatusResponse(path);
} }
const call = new Http2ServerCallStream(stream, handler); const call = new Http2ServerCallStream(stream, handler);

View File

@ -843,25 +843,34 @@ Server.prototype.forceShutdown = function() {
this._server.forceShutdown(); this._server.forceShutdown();
}; };
var unimplementedStatusResponse = { function getUnimplementedStatusResponse(methodName) {
return {
code: constants.status.UNIMPLEMENTED, code: constants.status.UNIMPLEMENTED,
details: 'The server does not implement this method' details: 'The server does not implement the method' + methodName
}; }
}
var defaultHandler = { function getDefaultHandler(handlerType, methodName) {
unary: function(call, callback) { const unimplementedStatusResponse = getUnimplementedStatusResponse(methodName);
callback(unimplementedStatusResponse); switch(handlerType) {
}, case 'unary':
client_stream: function(call, callback) { return (call, callback) => {
callback(unimplementedStatusResponse); callback(unimplementedStatusResponse, null);
}, };
server_stream: function(call) { case 'client_stream':
call.emit('error', unimplementedStatusResponse); return (call,callback) => {
}, callback(unimplementedStatusResponse, null);
bidi: function(call) { };
case 'server_stream':
return (call) => {
call.emit('error', unimplementedStatusResponse); call.emit('error', unimplementedStatusResponse);
} }
}; case 'bidi':
return (call) => {
call.emit('error', unimplementedStatusResponse);
}
}
}
function isObject(thing) { function isObject(thing) {
return (typeof thing === 'object' || typeof thing === 'function') && thing !== null; return (typeof thing === 'object' || typeof thing === 'function') && thing !== null;
@ -908,7 +917,7 @@ Server.prototype.addService = function(service, implementation) {
if (implementation[attrs.originalName] === undefined) { if (implementation[attrs.originalName] === undefined) {
common.log(constants.logVerbosity.ERROR, 'Method handler ' + name + common.log(constants.logVerbosity.ERROR, 'Method handler ' + name +
' for ' + attrs.path + ' expected but not provided'); ' for ' + attrs.path + ' expected but not provided');
impl = defaultHandler[method_type]; impl = getDefaultHandler(method_type, name);
} else { } else {
impl = implementation[attrs.originalName].bind(implementation); impl = implementation[attrs.originalName].bind(implementation);
} }