2016-11-24 25 views
9

Stworzyłem prosty serwer i klienta GRPC.Czy mogę wysłać niestandardowy komunikat o błędzie z serwera do klienta GRPC?

Co chcę zrobić, to utworzyć niestandardowy błąd na serwerze i przekazać go do klienta. Mój kod wygląda następująco:

Server.js

var error = require('error'); 

var PROTO_PATH = grpc.load(__dirname + '/proto/hello.proto'); 
var hello_proto = PROTO_PATH.hello; 

function sayHello(call, callback) { 

    try { 
     var jsErr = new Error('MY_ERROR'); 
     jsErr.newStatus = 401; 
     jsErr.newMessage = 'custom unAuthorized error'; 
     console.log(Object.getOwnPropertyNames(jsErr)); 
     console.log(jsErr); 
     callback(jsErr); 

    } catch(e) { 
     callback(e); 
    } 
} 

function sayHelloAgain(call, callback) { 
    callback(null, {message: 'Hello Again ' + call.request.name}); 
} 

function main() { 

    var server = new grpc.Server(); 
    server.addProtoService(hello_proto.Hello.service, {sayHello: sayHello,sayHelloAgain: sayHelloAgain }); 
    server.bind('0.0.0.0:50051', grpc.ServerCredentials.createInsecure()); 
    server.start(); 
} 

main(); 

Client.js

var grpc = require('grpc'); 

var PROTO_PATH = grpc.load(__dirname + '/proto/hello.proto'); 
var hello_proto = PROTO_PATH.hello; 

function main() { 
    var client = new hello_proto.Hello('localhost:50051',grpc.credentials.createInsecure()); 
    var user; 
    if (process.argv.length >= 3) { 
     user = process.argv[2]; 
    } else { 
     user = 'world'; 
    } 

    client.sayHello({name: user}, function(err, response) { 

     console.log(Object.getOwnPropertyNames(err)); 
     console.log(err); 
    }); 
} 

main(); 

i mój plik proto

syntax = "proto3"; 

package hello; 

service Hello { 
    rpc sayHello(sayHelloRequest) returns (sayHelloResponse) {} 
    rpc sayHelloAgain(sayHelloRequest) returns (sayHelloResponse) {} 
} 


message sayHelloRequest { 
    string name = 1; 
} 

message sayHelloResponse { 
    string message = 1; 
} 

gdy uruchomię cient wynik z każdego wygląda jak t jego serwer o numerze

.

[ 'stack', 'message', 'newStatus', 'newMessage' ] 
{ [Error: MY_ERROR] newStatus: 401, newMessage: 'custom unAutorized error' } 

Klient.

[ 'stack', 'message', 'code', 'metadata' ] 
{ [Error: MY_ERROR] code: 2, metadata: Metadata { _internal_repr: {} } } 

więc mój stworzył niestandardowe funkcje Javascript Błąd w newStatus, newMessage właściwości zostały usunięte i został przekształcony do GRPC wiadomości błąd standardowy.

Moje pytania są

  1. Czy jest możliwe, aby wysłać wiadomość do niestandardowego klienta?
  2. Czy mogę utworzyć błąd GRPC, a nie błąd javascript?
  3. Jednym ze sposobów wysyłania niestandardowych atrybutów do klienta jest, moim zdaniem, dodanie niestandardowych danych do Metadata. ale nie jestem również pewien, jak to zrobić.

Odpowiedz

1

1.TAK 2.Maybe

unikać wysyłania specjalnych przedmiotów (jak new Error) ponad drutu. Wyślij prosty obiekt z właściwością błędu i poszukaj jego wartości na drugim końcu. Zobacz http://json.org/, aby uzyskać przegląd łatwych do przesłania danych.

wewnątrz Server.js spróbować

function sayHello(call, callback) { 

    try { 
     var myCustomError = {}; 
     myCustomError.newStatus = 401; 
     myCustomError.newMessage = 'custom unAuthorized error'; 
     console.log(Object.getOwnPropertyNames(myCustomError)); 
     console.log(myCustomError); 
     callback(null, {error: myCustomError, message: ""}); 

    } catch(e) { 
     callback(e); 
    } 
} 

wewnątrz Client.js

client.sayHello({name: user}, function(err, response) { 
    var myCustomError= response.error; 
    if (myCustomError) { 
     console.log(Object.getOwnPropertyNames(myCustomError)); 
     console.log(myCustomError); 
    } 
}); 
+0

Hm mogę to zrozumieć. ale chcę wysłać mój błąd w pierwszym parametrze, jako obiekt błędu, w twoim przykładzie przekazujesz go w parametrze 2 nd i nie jest obiektem błędu. –

1

Jest pomocny odpowiedź na to samo pytanie na gRPC Google Grupa: https://groups.google.com/d/msg/grpc-io/X_bUx3T8S7s/x38FU429CgAJ

Możesz wysłać niestandardowy komunikat o stanie do klienta, używając błędu właściwość komunikatu obiektu. W twoim przykładzie jest to "MY_ERROR". Kod stanu powinien znajdować się we właściwości "code", podobnie jak po stronie klienta: .

Jeśli chcesz użyć struktury statusu gRPC zamiast błędu JavaScript , możesz to zrobić, wypełniając właściwość "code" i "detail" obiektu.

Jeśli chcesz wysłać metadane, powinieneś zbudować instancję klasy grpc.Metadata, a następnie dodać pary klucz/wartość do wynikowego obiektu. Następnie można przekazać go jako trzeci argument wywołania zwrotnego lub ustawić właściwość "metadanych" błędu błędu , aby wysłać go do klienta z błędem.

Należy pamiętać, że kody stanu, których używa gRPC, nie są kodami statusu HTTP , ale kody specyficzne dla gRPC zdefiniowane w pliku grpc.status. Ty powinieneś tylko ustawić właściwość code błędu za pomocą tych kodów. Jeśli chcesz wysłać własne kody, użyj zamiast nich metadanych.

Zilustruję to, co zostało napisane powyżej, z kilkoma przykładami.

Aby wysłać niestandardową wiadomość z błędem, należy skonstruować wiadomość o numerze Error. To ustawia właściwość message:

var jsErr = new Error('Unauthorized'); 

Jak wspomniano powyżej, to chyba nie warto bezpośrednio ustawić kody stanu gRPC w Twoim przypadku. Ale, w celach informacyjnych, kod stanu gRPC można ustawić poprzez Błąd w code nieruchomości:

jsErr.code = grpc.status.PERMISSION_DENIED; 

aby wysłać swoje własne kody błędu lub innych informacji, metadane zastosowanie:

var metadata = new grpc.Metadata(); 
metadata.set('key1', 'value2'); 
metadata.set('key2', 'value2'); 

jsErr.metadata = metadata; 

Teraz, gdy serwer konstruuje błąd jak wyżej, a klient wysyła zwracany błąd z:

console.log(Object.getOwnPropertyNames(err)); 
console.log(err); 
console.log(err.metadata); 

następnie wyjście klient jest:

[ 'stack', 'message', 'code', 'metadata' ] 
{ [Error: Unauthorized] 
    code: 7, 
    metadata: Metadata { _internal_repr: { key1: [Object], key2: [Object] } } } 
Metadata { _internal_repr: { key1: [ 'value2' ], key2: [ 'value2' ] } } 
+0

Właściwie to pytanie jest również zadawane przeze mnie: D. Myślałem, że będzie więcej sposobów. w każdym razie bardzo dziękuję za odpowiedź (Y) –

Powiązane problemy