diff --git a/packages/grpc-js/src/server.ts b/packages/grpc-js/src/server.ts index a2db30be..9cddb084 100644 --- a/packages/grpc-js/src/server.ts +++ b/packages/grpc-js/src/server.ts @@ -49,11 +49,15 @@ import { ChannelOptions } from './channel-options'; function noop(): void {} -const unimplementedStatusResponse: Partial = { - code: Status.UNIMPLEMENTED, - details: 'The server does not implement this method', - metadata: new Metadata(), -}; +function getUnimplementedStatusResponse( + methodName: string +): Partial { + return { + code: Status.UNIMPLEMENTED, + details: `The server does not implement the method ${methodName}`, + metadata: new Metadata(), + }; +} // tslint:disable:no-any type UntypedUnaryHandler = UnaryHandler; @@ -66,23 +70,37 @@ export interface UntypedServiceImplementation { [name: string]: UntypedHandleCall; } -const defaultHandler = { - unary(call: ServerUnaryCall, callback: sendUnaryData): void { - callback(unimplementedStatusResponse as ServiceError, null); - }, - clientStream( - call: ServerReadableStream, - callback: sendUnaryData - ): void { - callback(unimplementedStatusResponse as ServiceError, null); - }, - serverStream(call: ServerWritableStream): void { - call.emit('error', unimplementedStatusResponse); - }, - bidi(call: ServerDuplexStream): void { - call.emit('error', unimplementedStatusResponse); - }, -}; +function getDefaultHandler(handlerType: HandlerType, methodName: string) { + const unimplementedStatusResponse = getUnimplementedStatusResponse( + methodName + ); + switch (handlerType) { + case 'unary': + return ( + call: ServerUnaryCall, + callback: sendUnaryData + ) => { + callback(unimplementedStatusResponse as ServiceError, null); + }; + case 'clientStream': + return ( + call: ServerReadableStream, + callback: sendUnaryData + ) => { + callback(unimplementedStatusResponse as ServiceError, null); + }; + case 'serverStream': + return (call: ServerWritableStream) => { + call.emit('error', unimplementedStatusResponse); + }; + case 'bidi': + return (call: ServerDuplexStream) => { + call.emit('error', unimplementedStatusResponse); + }; + default: + throw new Error(`Invalid handlerType ${handlerType}`); + } +} // tslint:enable:no-any export class Server { @@ -157,7 +175,7 @@ export class Server { if (implFn !== undefined) { impl = implFn.bind(implementation); } else { - impl = defaultHandler[methodType]; + impl = getDefaultHandler(methodType, name); } const success = this.register( @@ -353,7 +371,7 @@ export class Server { const handler = this.handlers.get(path); if (handler === undefined) { - throw unimplementedStatusResponse; + throw getUnimplementedStatusResponse(path); } const call = new Http2ServerCallStream(stream, handler); diff --git a/packages/grpc-native-core/src/server.js b/packages/grpc-native-core/src/server.js index 737e4314..81e56347 100644 --- a/packages/grpc-native-core/src/server.js +++ b/packages/grpc-native-core/src/server.js @@ -843,25 +843,34 @@ Server.prototype.forceShutdown = function() { this._server.forceShutdown(); }; -var unimplementedStatusResponse = { - code: constants.status.UNIMPLEMENTED, - details: 'The server does not implement this method' -}; - -var defaultHandler = { - unary: function(call, callback) { - callback(unimplementedStatusResponse); - }, - client_stream: function(call, callback) { - callback(unimplementedStatusResponse); - }, - server_stream: function(call) { - call.emit('error', unimplementedStatusResponse); - }, - bidi: function(call) { - call.emit('error', unimplementedStatusResponse); +function getUnimplementedStatusResponse(methodName) { + return { + code: constants.status.UNIMPLEMENTED, + details: 'The server does not implement the method' + methodName } -}; +} + +function getDefaultHandler(handlerType, methodName) { + const unimplementedStatusResponse = getUnimplementedStatusResponse(methodName); + switch(handlerType) { + case 'unary': + return (call, callback) => { + callback(unimplementedStatusResponse, null); + }; + case 'client_stream': + return (call,callback) => { + callback(unimplementedStatusResponse, null); + }; + case 'server_stream': + return (call) => { + call.emit('error', unimplementedStatusResponse); + } + case 'bidi': + return (call) => { + call.emit('error', unimplementedStatusResponse); + } + } +} function isObject(thing) { return (typeof thing === 'object' || typeof thing === 'function') && thing !== null; @@ -908,7 +917,7 @@ Server.prototype.addService = function(service, implementation) { if (implementation[attrs.originalName] === undefined) { common.log(constants.logVerbosity.ERROR, 'Method handler ' + name + ' for ' + attrs.path + ' expected but not provided'); - impl = defaultHandler[method_type]; + impl = getDefaultHandler(method_type, name); } else { impl = implementation[attrs.originalName].bind(implementation); }