异常类型返回值

当服务端请求处理失败时,dubbo 会支持返回 error 类型值,本示例演示如何处理异常类型返回值。

1.介绍

本文档演示如何在 RPC 调用过程中处理 error 错误类型响应,可在此查看 完整示例源码地址

2.示例详解

2.1 服务端

服务端proto文件

源文件路径:dubbo-go-sample/error/proto/greet.proto

  1. syntax = "proto3";
  2. package greet;
  3. option go_package = "github.com/apache/dubbo-go-samples/error/proto;greet";
  4. message GreetRequest {
  5. string name = 1;
  6. }
  7. message GreetResponse {
  8. string greeting = 1;
  9. }
  10. service GreetService {
  11. rpc Greet(GreetRequest) returns (GreetResponse) {}
  12. }

服务端handler文件

请注意,在本程序设计中,Greet方法只有接收到 name="right name" 时才会认为是正确请求,否则会返回错误。

源文件路径:dubbo-go-sample/context/go-server/main.go

  1. package main
  2. import (
  3. "context"
  4. "fmt"
  5. "github.com/pkg/errors"
  6. _ "dubbo.apache.org/dubbo-go/v3/imports"
  7. "dubbo.apache.org/dubbo-go/v3/protocol"
  8. "dubbo.apache.org/dubbo-go/v3/server"
  9. greet "github.com/apache/dubbo-go-samples/helloworld/proto"
  10. "github.com/dubbogo/gost/log/logger"
  11. )
  12. type GreetTripleServer struct {
  13. }
  14. func (srv *GreetTripleServer) Greet(ctx context.Context, req *greet.GreetRequest) (*greet.GreetResponse, error) {
  15. name := req.Name
  16. if name != "right name" {
  17. errInfo := fmt.Sprintf("name is not right: %s", name)
  18. logger.Error(errInfo)
  19. return nil, errors.New(errInfo)
  20. }
  21. resp := &greet.GreetResponse{Greeting: req.Name}
  22. return resp, nil
  23. }
  24. func main() {
  25. srv, err := server.NewServer(
  26. server.WithServerProtocol(
  27. protocol.WithPort(20000),
  28. protocol.WithTriple(),
  29. ),
  30. )
  31. if err != nil {
  32. panic(err)
  33. }
  34. if err = greet.RegisterGreetServiceHandler(srv, &GreetTripleServer{}); err != nil {
  35. panic(err)
  36. }
  37. if err = srv.Serve(); err != nil {
  38. logger.Error(err)
  39. }
  40. }

从 rpc 方法签名中,我们可以看到 func (srv *GreetTripleServer) Greet(ctx context.Context, req *greet.GreetRequest) (*greet.GreetResponse, error) 包含 error 返回值。

2.2 客户端

客户端分别发起两次调用,一次是正确的请求,一次是错误的请求

源文件路径:dubbo-go-sample/context/go-client/main.go

  1. package main
  2. import (
  3. "context"
  4. "dubbo.apache.org/dubbo-go/v3/client"
  5. _ "dubbo.apache.org/dubbo-go/v3/imports"
  6. greet "github.com/apache/dubbo-go-samples/helloworld/proto"
  7. "github.com/dubbogo/gost/log/logger"
  8. )
  9. func main() {
  10. cli, err := client.NewClient(
  11. client.WithClientURL("127.0.0.1:20000"),
  12. )
  13. if err != nil {
  14. panic(err)
  15. }
  16. svc, err := greet.NewGreetService(cli)
  17. if err != nil {
  18. panic(err)
  19. }
  20. resp, err := svc.Greet(context.Background(), &greet.GreetRequest{Name: "right name"})
  21. if err != nil {
  22. logger.Error(err)
  23. }
  24. logger.Infof("call Greet success: %s", resp.Greeting)
  25. resp, err = svc.Greet(context.Background(), &greet.GreetRequest{Name: "wrong name"})
  26. if err != nil {
  27. logger.Errorf("call Greet failed, err: %s", err.Error())
  28. }
  29. }

2.3 案例效果

先启动服务端,再启动客户端,可以观察到客户端的第一次调用成功,第二次调用失败并且服务端返回了 error

  1. 2024-02-28 17:49:40 INFO logger/logging.go:42 call Greet success: [right name]
  2. 2024-02-28 17:49:40 ERROR logger/logging.go:52 call Greet failed, err: [Failed to invoke the method Greet in the service greet.GreetService. Tried 2 times of the providers [tri://:@127.0.0.1:20000/?interface=greet.GreetService&group=&version= tri://:@127.0.0.1:20000/?interface=greet.GreetService&group=&version= tri://:@127.0.0.1:20000/?interface=greet.GreetService&group=&version=] (3/1)from the registry tri://127.0.0.1:20000/greet.GreetService?app.version=&application=dubbo.io&async=false&bean.name=greet.GreetService&cluster=failover&config.tracing=&environment=&generic=&group=&interface=greet.GreetService&loadbalance=&metadata-type=local&module=sample&name=dubbo.io&organization=dubbo-go&owner=dubbo-go&peer=true&provided-by=&reference.filter=cshutdown&registry.role=0&release=dubbo-golang-3.2.0&remote.timestamp=&retries=&serialization=protobuf&side=consumer&sticky=false&timestamp=1709113780&version= on the consumer 30.221.146.234 using the dubbo version 3.2.0. Last error is unknown: name is not right: wrong name.: unknown: name is not right: wrong name]

最后修改 September 13, 2024: Refactor website structure (#2860) (1a4b998f54b)