mirror of https://github.com/grpc/grpc-node.git
Merge pull request #2528 from murgatroid99/grpc-js_unimplemented_message_fix
grpc-js: Fix propagation of UNIMPLEMENTED error messages
This commit is contained in:
commit
15a3f1a31c
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@grpc/grpc-js",
|
||||
"version": "1.8.20",
|
||||
"version": "1.8.21",
|
||||
"description": "gRPC Library for Node - pure JS implementation",
|
||||
"homepage": "https://grpc.io/",
|
||||
"repository": "https://github.com/grpc/grpc-node/tree/master/packages/grpc-js",
|
||||
|
|
|
@ -61,7 +61,6 @@ import {
|
|||
import { parseUri } from './uri-parser';
|
||||
import { ChannelzCallTracker, ChannelzChildrenTracker, ChannelzTrace, registerChannelzServer, registerChannelzSocket, ServerInfo, ServerRef, SocketInfo, SocketRef, TlsInfo, unregisterChannelzRef } from './channelz';
|
||||
import { CipherNameAndProtocol, TLSSocket } from 'tls';
|
||||
import { getErrorCode, getErrorMessage } from './error';
|
||||
|
||||
const UNLIMITED_CONNECTION_AGE_MS = ~(1<<31);
|
||||
const KEEPALIVE_MAX_TIME_MS = ~(1<<31);
|
||||
|
@ -765,9 +764,7 @@ export class Server {
|
|||
return true
|
||||
}
|
||||
|
||||
private _retrieveHandler(headers: http2.IncomingHttpHeaders): Handler<any, any> {
|
||||
const path = headers[HTTP2_HEADER_PATH] as string
|
||||
|
||||
private _retrieveHandler(path: string): Handler<any, any> | null {
|
||||
this.trace(
|
||||
'Received call to method ' +
|
||||
path +
|
||||
|
@ -783,7 +780,7 @@ export class Server {
|
|||
path +
|
||||
'. Sending UNIMPLEMENTED status.'
|
||||
);
|
||||
throw getUnimplementedStatusResponse(path);
|
||||
return null;
|
||||
}
|
||||
|
||||
return handler
|
||||
|
@ -820,15 +817,12 @@ export class Server {
|
|||
return
|
||||
}
|
||||
|
||||
let handler: Handler<any, any>
|
||||
try {
|
||||
handler = this._retrieveHandler(headers)
|
||||
} catch (err) {
|
||||
this._respondWithError({
|
||||
details: getErrorMessage(err),
|
||||
code: getErrorCode(err) ?? undefined
|
||||
}, stream, channelzSessionInfo)
|
||||
return
|
||||
const path = headers[HTTP2_HEADER_PATH] as string;
|
||||
|
||||
const handler = this._retrieveHandler(path);
|
||||
if (!handler) {
|
||||
this._respondWithError(getUnimplementedStatusResponse(path), stream, channelzSessionInfo);
|
||||
return;
|
||||
}
|
||||
|
||||
const call = new Http2ServerCallStream(stream, handler, this.options);
|
||||
|
@ -875,15 +869,13 @@ export class Server {
|
|||
return
|
||||
}
|
||||
|
||||
let handler: Handler<any, any>
|
||||
try {
|
||||
handler = this._retrieveHandler(headers)
|
||||
} catch (err) {
|
||||
this._respondWithError({
|
||||
details: getErrorMessage(err),
|
||||
code: getErrorCode(err) ?? undefined
|
||||
}, stream, null)
|
||||
return
|
||||
|
||||
const path = headers[HTTP2_HEADER_PATH] as string;
|
||||
|
||||
const handler = this._retrieveHandler(path);
|
||||
if (!handler) {
|
||||
this._respondWithError(getUnimplementedStatusResponse(path), stream, null);
|
||||
return;
|
||||
}
|
||||
|
||||
const call = new Http2ServerCallStream(stream, handler, this.options)
|
||||
|
|
|
@ -408,6 +408,7 @@ describe('Server', () => {
|
|||
(error: ServiceError, response: any) => {
|
||||
assert(error);
|
||||
assert.strictEqual(error.code, grpc.status.UNIMPLEMENTED);
|
||||
assert.match(error.details, /does not implement the method.*Div/);
|
||||
done();
|
||||
}
|
||||
);
|
||||
|
@ -417,6 +418,7 @@ describe('Server', () => {
|
|||
const call = client.sum((error: ServiceError, response: any) => {
|
||||
assert(error);
|
||||
assert.strictEqual(error.code, grpc.status.UNIMPLEMENTED);
|
||||
assert.match(error.details, /does not implement the method.*Sum/);
|
||||
done();
|
||||
});
|
||||
|
||||
|
@ -433,6 +435,7 @@ describe('Server', () => {
|
|||
call.on('error', (err: ServiceError) => {
|
||||
assert(err);
|
||||
assert.strictEqual(err.code, grpc.status.UNIMPLEMENTED);
|
||||
assert.match(err.details, /does not implement the method.*Fib/);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
@ -447,6 +450,93 @@ describe('Server', () => {
|
|||
call.on('error', (err: ServiceError) => {
|
||||
assert(err);
|
||||
assert.strictEqual(err.code, grpc.status.UNIMPLEMENTED);
|
||||
assert.match(err.details, /does not implement the method.*DivMany/);
|
||||
done();
|
||||
});
|
||||
|
||||
call.end();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Unregistered service', () => {
|
||||
let server: Server;
|
||||
let client: ServiceClient;
|
||||
|
||||
const mathProtoFile = path.join(__dirname, 'fixtures', 'math.proto');
|
||||
const mathClient = (loadProtoFile(mathProtoFile).math as any).Math;
|
||||
|
||||
before(done => {
|
||||
server = new Server();
|
||||
// Don't register a service at all
|
||||
server.bindAsync(
|
||||
'localhost:0',
|
||||
ServerCredentials.createInsecure(),
|
||||
(err, port) => {
|
||||
assert.ifError(err);
|
||||
client = new mathClient(
|
||||
`localhost:${port}`,
|
||||
grpc.credentials.createInsecure()
|
||||
);
|
||||
server.start();
|
||||
done();
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
after(done => {
|
||||
client.close();
|
||||
server.tryShutdown(done);
|
||||
});
|
||||
|
||||
it('should respond to a unary call with UNIMPLEMENTED', done => {
|
||||
client.div(
|
||||
{ divisor: 4, dividend: 3 },
|
||||
(error: ServiceError, response: any) => {
|
||||
assert(error);
|
||||
assert.strictEqual(error.code, grpc.status.UNIMPLEMENTED);
|
||||
assert.match(error.details, /does not implement the method.*Div/);
|
||||
done();
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('should respond to a client stream with UNIMPLEMENTED', done => {
|
||||
const call = client.sum((error: ServiceError, response: any) => {
|
||||
assert(error);
|
||||
assert.strictEqual(error.code, grpc.status.UNIMPLEMENTED);
|
||||
assert.match(error.details, /does not implement the method.*Sum/);
|
||||
done();
|
||||
});
|
||||
|
||||
call.end();
|
||||
});
|
||||
|
||||
it('should respond to a server stream with UNIMPLEMENTED', done => {
|
||||
const call = client.fib({ limit: 5 });
|
||||
|
||||
call.on('data', (value: any) => {
|
||||
assert.fail('No messages expected');
|
||||
});
|
||||
|
||||
call.on('error', (err: ServiceError) => {
|
||||
assert(err);
|
||||
assert.strictEqual(err.code, grpc.status.UNIMPLEMENTED);
|
||||
assert.match(err.details, /does not implement the method.*Fib/);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should respond to a bidi call with UNIMPLEMENTED', done => {
|
||||
const call = client.divMany();
|
||||
|
||||
call.on('data', (value: any) => {
|
||||
assert.fail('No messages expected');
|
||||
});
|
||||
|
||||
call.on('error', (err: ServiceError) => {
|
||||
assert(err);
|
||||
assert.strictEqual(err.code, grpc.status.UNIMPLEMENTED);
|
||||
assert.match(err.details, /does not implement the method.*DivMany/);
|
||||
done();
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in New Issue