web-dev-qa-db-ja.com

カスタムエラーメッセージをサーバーからクライアントGRPCに送信できますか?

簡単なGRPCサーバーとクライアントを作成しました。

私がしたいことは、サーバーでカスタムエラーを作成し、それをクライアントに渡すことです。私のコードは次のようになります:

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();

そして私のプロトファイル

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;
}

cientを実行すると、それぞれの結果は次のようになります

サーバー。

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

クライアント。

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

だから私が作成したカスタムJavaScriptエラーのnewStatus, newMessageプロパティが削除され、GRPC標準エラーメッセージに変換されました。

私の質問は

  1. カスタムメッセージをクライアントに送信することはできますか?
  2. JavaScriptエラーではなく、GRPCエラーを作成できますか?
  3. カスタム属性をクライアントに送信する1つの方法は、カスタムデータをMetadataに追加することです。しかし、私はそれを行う方法もわかりません。

GRPC Googleグループでこの同じ質問に役立つ回答があります: https://groups.google.com/d/msg/grpc-io/X_bUx3T8S7s/x38FU429CgAJ

Errorオブジェクトのmessageプロパティを使用して、カスタムステータスメッセージをクライアントに送信できます。あなたの例では、それは「MY_ERROR」です。ステータスコードは、クライアント側での表示と同じように、「コード」プロパティにある必要があります。

JavaScriptエラーの代わりにgRPCステータス構造を使用する場合は、オブジェクトの「code」プロパティと「message」または「details」プロパティを設定することで使用できます。

メタデータを送信する場合は、grpc.Metadataクラスのインスタンスを作成し、結果のオブジェクトにキーと値のペアを追加する必要があります。次に、それをコールバックの3番目の引数として渡すか、エラーの「メタデータ」プロパティを設定して、エラーのあるクライアントに送信できます。

GRPCが使用するステータスコードはHTTPステータスコードではなく、grpc.statusで定義されているgRPC固有のコードであることに注意してください。これらのコードを使用して、エラーのコードプロパティのみを設定する必要があります。独自のコードを送信する場合は、代わりにメタデータを使用してください。

上記の内容を例を挙げて説明します。

エラーのあるカスタムメッセージを送信するには、メッセージを使用してErrorを作成します。これはmessageプロパティを設定します:

var jsErr = new Error('Unauthorized');

上記のように、gRPCステータスコードを直接設定することはおそらく役に立ちません。ただし、参考までに、gRPCステータスコードはエラーのcodeプロパティを通じて設定できます。

jsErr.code = grpc.status.PERMISSION_DENIED;

独自のエラーコードまたはその他の情報を送信するには、メタデータを使用します。

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

jsErr.metadata = metadata;

ここで、サーバーが上記のようにエラーを作成し、クライアントが返されたエラーを次のように出力した場合:

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

クライアントの出力は次のとおりです。

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

1.はい2.たぶん

特殊オブジェクト(new Errorなど)をネットワーク経由で送信しないでください。エラープロパティを持つ単純なオブジェクトを送信し、もう一方の端でその値を探します。簡単に転送できるデータの概要については、 http://json.org/ を参照してください。

server.jsの内部

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);
    }
}

client.js内

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