Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/421.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/38.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 我可以从服务器向客户端GRPC发送自定义错误消息吗?_Javascript_Node.js_Protocol Buffers_Grpc - Fatal编程技术网

Javascript 我可以从服务器向客户端GRPC发送自定义错误消息吗?

Javascript 我可以从服务器向客户端GRPC发送自定义错误消息吗?,javascript,node.js,protocol-buffers,grpc,Javascript,Node.js,Protocol Buffers,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 {

我创建了一个简单的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();
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();
Client.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();
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标准错误消息

我的问题是

  • 是否可以向客户端发送自定义消息
  • 我可以创建GRPC错误而不是javascript错误吗
  • 向客户端发送自定义属性的一种方法是将自定义数据添加到
    元数据中。但我也不知道怎么做
    1.是的2.也许

    避免通过导线发送特殊对象(如
    新错误
    )。发送带有错误属性的简单对象,并在另一端查找其值。请参阅,以了解易转移数据的概述

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

    gRPC谷歌集团对同样的问题有一个有用的回答:

    您可以使用错误消息向客户端发送自定义状态消息 对象的消息属性。在你的例子中,这就是“我的错误”。这个 状态代码应该在“code”属性中,就像您所看到的一样 在客户端

    如果您想使用gRPC状态结构而不是JavaScript 错误,您可以通过填充“code”属性和 对象的“消息”或“详细信息”属性

    如果要发送元数据,应该构造 元数据类,然后将键/值对添加到结果对象中。 然后可以将其作为回调的第三个参数传递,或者设置 错误的“元数据”属性将其发送到带有错误的客户端

    请注意,gRPC使用的状态代码不是HTTP状态 代码,但gRPC.status中定义的gRPC特定代码。你 应仅使用这些代码设置错误的代码属性。如果你 要发送自己的代码,请使用元数据

    我将用一些例子来说明上面写的内容

    要发送带有错误的自定义消息,请使用该消息构造一个
    错误
    。这将设置
    消息
    属性:

    var jsErr = new Error('Unauthorized');
    
    jsErr.code = grpc.status.PERMISSION_DENIED;
    
    如上所述,在您的案例中直接设置gRPC状态代码可能没有用。但是,作为参考,gRPC状态代码可以通过错误的
    code
    属性设置:

    var jsErr = new Error('Unauthorized');
    
    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' ] } }
    

    实际上我也问了这个问题:D。我以为会有更多的方法。无论如何,非常感谢你的回答。嗯,我能理解。但是我想在第一个参数中发送我的错误,作为一个错误对象,在您的示例中,您在第二个参数中传递它,而它不是一个错误对象。