Skip to content

Commit

Permalink
add warden rpc (go-kratos#9)
Browse files Browse the repository at this point in the history
* add warden rpc
  • Loading branch information
longXboy authored and felixhao committed Apr 12, 2019
1 parent 50d0129 commit 637a6a3
Show file tree
Hide file tree
Showing 61 changed files with 7,802 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
go.sum
BUILD
.DS_Store
tool/kratos/kratos
18 changes: 18 additions & 0 deletions pkg/conf/flagvar/flagvar.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package flagvar

import (
"strings"
)

// StringVars []string implement flag.Value
type StringVars []string

func (s StringVars) String() string {
return strings.Join(s, ",")
}

// Set implement flag.Value
func (s *StringVars) Set(val string) error {
*s = append(*s, val)
return nil
}
1 change: 1 addition & 0 deletions pkg/ecode/common_ecode.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ var (
NothingFound = add(-404) // 啥都木有
MethodNotAllowed = add(-405) // 不支持该方法
Conflict = add(-409) // 冲突
Canceled = add(-498) // 客户端取消请求
ServerErr = add(-500) // 服务器错误
ServiceUnavailable = add(-503) // 过载保护,服务暂不可用
Deadline = add(-504) // 服务调用超时
Expand Down
48 changes: 48 additions & 0 deletions pkg/ecode/pb/ecode.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package pb

import (
"strconv"

"github.com/bilibili/kratos/pkg/ecode"

any "github.com/golang/protobuf/ptypes/any"
)

func (e *Error) Error() string {
return strconv.FormatInt(int64(e.GetErrCode()), 10)
}

// Code is the code of error.
func (e *Error) Code() int {
return int(e.GetErrCode())
}

// Message is error message.
func (e *Error) Message() string {
return e.GetErrMessage()
}

// Equal compare whether two errors are equal.
func (e *Error) Equal(ec error) bool {
return ecode.Cause(ec).Code() == e.Code()
}

// Details return error details.
func (e *Error) Details() []interface{} {
return []interface{}{e.GetErrDetail()}
}

// From will convert ecode.Codes to pb.Error.
//
// Deprecated: please use ecode.Error
func From(ec ecode.Codes) *Error {
var detail *any.Any
if details := ec.Details(); len(details) > 0 {
detail, _ = details[0].(*any.Any)
}
return &Error{
ErrCode: int32(ec.Code()),
ErrMessage: ec.Message(),
ErrDetail: detail,
}
}
96 changes: 96 additions & 0 deletions pkg/ecode/pb/ecode.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 13 additions & 0 deletions pkg/ecode/pb/ecode.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
syntax = "proto3";

package pb;

import "google/protobuf/any.proto";

option go_package = "go-common/library/ecode/pb";

message Error {
int32 err_code = 1;
string err_message = 2;
google.protobuf.Any err_detail = 3;
}
103 changes: 103 additions & 0 deletions pkg/ecode/status.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package ecode

import (
"fmt"
"strconv"

"github.com/bilibili/kratos/pkg/ecode/types"
"github.com/golang/protobuf/proto"
"github.com/golang/protobuf/ptypes"
)

// Error new status with code and message
func Error(code Code, message string) *Status {
return &Status{s: &types.Status{Code: int32(code.Code()), Message: message}}
}

// Errorf new status with code and message
func Errorf(code Code, format string, args ...interface{}) *Status {
return Error(code, fmt.Sprintf(format, args...))
}

var _ Codes = &Status{}

// Status statusError is an alias of a status proto
// implement ecode.Codes
type Status struct {
s *types.Status
}

// Error implement error
func (s *Status) Error() string {
return s.Message()
}

// Code return error code
func (s *Status) Code() int {
return int(s.s.Code)
}

// Message return error message for developer
func (s *Status) Message() string {
if s.s.Message == "" {
return strconv.Itoa(int(s.s.Code))
}
return s.s.Message
}

// Details return error details
func (s *Status) Details() []interface{} {
if s == nil || s.s == nil {
return nil
}
details := make([]interface{}, 0, len(s.s.Details))
for _, any := range s.s.Details {
detail := &ptypes.DynamicAny{}
if err := ptypes.UnmarshalAny(any, detail); err != nil {
details = append(details, err)
continue
}
details = append(details, detail.Message)
}
return details
}

// WithDetails WithDetails
func (s *Status) WithDetails(pbs ...proto.Message) (*Status, error) {
for _, pb := range pbs {
anyMsg, err := ptypes.MarshalAny(pb)
if err != nil {
return s, err
}
s.s.Details = append(s.s.Details, anyMsg)
}
return s, nil
}

// Equal for compatible.
// Deprecated: please use ecode.EqualError.
func (s *Status) Equal(err error) bool {
return EqualError(s, err)
}

// Proto return origin protobuf message
func (s *Status) Proto() *types.Status {
return s.s
}

// FromCode create status from ecode
func FromCode(code Code) *Status {
return &Status{s: &types.Status{Code: int32(code)}}
}

// FromProto new status from grpc detail
func FromProto(pbMsg proto.Message) Codes {
if msg, ok := pbMsg.(*types.Status); ok {
if msg.Message == "" {
// NOTE: if message is empty convert to pure Code, will get message from config center.
return Code(msg.Code)
}
return &Status{s: msg}
}
return Errorf(ServerErr, "invalid proto message get %v", pbMsg)
}
66 changes: 66 additions & 0 deletions pkg/ecode/status_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package ecode

import (
"testing"
"time"

"github.com/golang/protobuf/ptypes/timestamp"
"github.com/smartystreets/goconvey/convey"
"github.com/stretchr/testify/assert"

"github.com/bilibili/kratos/pkg/ecode/types"
)

func TestEqual(t *testing.T) {
convey.Convey("Equal", t, func(ctx convey.C) {
ctx.Convey("When err1=Error(RequestErr, 'test') and err2=Errorf(RequestErr, 'test')", func(ctx convey.C) {
err1 := Error(RequestErr, "test")
err2 := Errorf(RequestErr, "test")
ctx.Convey("Then err1=err2, err1 != nil", func(ctx convey.C) {
ctx.So(err1, convey.ShouldResemble, err2)
ctx.So(err1, convey.ShouldNotBeNil)
})
})
})
// assert.True(t, OK.Equal(nil))
// assert.True(t, err1.Equal(err2))
// assert.False(t, err1.Equal(nil))
// assert.True(t, Equal(nil, nil))
}

func TestDetail(t *testing.T) {
m := &timestamp.Timestamp{Seconds: time.Now().Unix()}
st, _ := Error(RequestErr, "RequestErr").WithDetails(m)

assert.Equal(t, "RequestErr", st.Message())
assert.Equal(t, int(RequestErr), st.Code())
assert.IsType(t, m, st.Details()[0])
}

func TestFromCode(t *testing.T) {
err := FromCode(RequestErr)

assert.Equal(t, int(RequestErr), err.Code())
assert.Equal(t, "-400", err.Message())
}

func TestFromProto(t *testing.T) {
msg := &types.Status{Code: 2233, Message: "error"}
err := FromProto(msg)

assert.Equal(t, 2233, err.Code())
assert.Equal(t, "error", err.Message())

m := &timestamp.Timestamp{Seconds: time.Now().Unix()}
err = FromProto(m)
assert.Equal(t, -500, err.Code())
assert.Contains(t, err.Message(), "invalid proto message get")
}

func TestEmpty(t *testing.T) {
st := &Status{}
assert.Len(t, st.Details(), 0)

st = nil
assert.Len(t, st.Details(), 0)
}
Loading

0 comments on commit 637a6a3

Please sign in to comment.