1
0
mirror of https://github.com/go-micro/go-micro.git synced 2024-12-18 08:26:38 +02:00

add MultiError type (#2297)

This commit is contained in:
Qalifah 2021-10-06 17:55:14 +01:00 committed by GitHub
parent 2ef523a7eb
commit a99a1e9356
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 305 additions and 77 deletions

View File

@ -160,3 +160,22 @@ func As(err error) (*Error, bool) {
}
return nil, false
}
func NewMultiError() *MultiError {
return &MultiError{
Errors: make([]*Error, 0),
}
}
func (e *MultiError) Append(err *Error) {
e.Errors = append(e.Errors, err)
}
func (e *MultiError) HasErrors() bool {
return len(e.Errors) > 0
}
func (e *MultiError) Error() string {
b, _ := json.Marshal(e)
return string(b)
}

View File

@ -1,102 +1,233 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: errors/errors.proto
// versions:
// protoc-gen-go v1.27.1
// protoc v3.13.0
// source: errors.proto
package errors
import (
fmt "fmt"
proto "github.com/golang/protobuf/proto"
math "math"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
type Error struct {
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
Code int32 `protobuf:"varint,2,opt,name=code,proto3" json:"code,omitempty"`
Detail string `protobuf:"bytes,3,opt,name=detail,proto3" json:"detail,omitempty"`
Status string `protobuf:"bytes,4,opt,name=status,proto3" json:"status,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
Code int32 `protobuf:"varint,2,opt,name=code,proto3" json:"code,omitempty"`
Detail string `protobuf:"bytes,3,opt,name=detail,proto3" json:"detail,omitempty"`
Status string `protobuf:"bytes,4,opt,name=status,proto3" json:"status,omitempty"`
}
func (m *Error) Reset() { *m = Error{} }
func (m *Error) String() string { return proto.CompactTextString(m) }
func (*Error) ProtoMessage() {}
func (x *Error) Reset() {
*x = Error{}
if protoimpl.UnsafeEnabled {
mi := &file_errors_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Error) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Error) ProtoMessage() {}
func (x *Error) ProtoReflect() protoreflect.Message {
mi := &file_errors_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Error.ProtoReflect.Descriptor instead.
func (*Error) Descriptor() ([]byte, []int) {
return fileDescriptor_85c4eef3398a32b2, []int{0}
return file_errors_proto_rawDescGZIP(), []int{0}
}
func (m *Error) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Error.Unmarshal(m, b)
}
func (m *Error) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_Error.Marshal(b, m, deterministic)
}
func (m *Error) XXX_Merge(src proto.Message) {
xxx_messageInfo_Error.Merge(m, src)
}
func (m *Error) XXX_Size() int {
return xxx_messageInfo_Error.Size(m)
}
func (m *Error) XXX_DiscardUnknown() {
xxx_messageInfo_Error.DiscardUnknown(m)
}
var xxx_messageInfo_Error proto.InternalMessageInfo
func (m *Error) GetId() string {
if m != nil {
return m.Id
func (x *Error) GetId() string {
if x != nil {
return x.Id
}
return ""
}
func (m *Error) GetCode() int32 {
if m != nil {
return m.Code
func (x *Error) GetCode() int32 {
if x != nil {
return x.Code
}
return 0
}
func (m *Error) GetDetail() string {
if m != nil {
return m.Detail
func (x *Error) GetDetail() string {
if x != nil {
return x.Detail
}
return ""
}
func (m *Error) GetStatus() string {
if m != nil {
return m.Status
func (x *Error) GetStatus() string {
if x != nil {
return x.Status
}
return ""
}
func init() {
proto.RegisterType((*Error)(nil), "errors.Error")
type MultiError struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Errors []*Error `protobuf:"bytes,1,rep,name=errors,proto3" json:"errors,omitempty"`
}
func init() { proto.RegisterFile("errors/errors.proto", fileDescriptor_85c4eef3398a32b2) }
var fileDescriptor_85c4eef3398a32b2 = []byte{
// 118 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x4e, 0x2d, 0x2a, 0xca,
0x2f, 0x2a, 0xd6, 0x87, 0x50, 0x7a, 0x05, 0x45, 0xf9, 0x25, 0xf9, 0x42, 0x6c, 0x10, 0x9e, 0x52,
0x34, 0x17, 0xab, 0x2b, 0x88, 0x25, 0xc4, 0xc7, 0xc5, 0x94, 0x99, 0x22, 0xc1, 0xa8, 0xc0, 0xa8,
0xc1, 0x19, 0xc4, 0x94, 0x99, 0x22, 0x24, 0xc4, 0xc5, 0x92, 0x9c, 0x9f, 0x92, 0x2a, 0xc1, 0xa4,
0xc0, 0xa8, 0xc1, 0x1a, 0x04, 0x66, 0x0b, 0x89, 0x71, 0xb1, 0xa5, 0xa4, 0x96, 0x24, 0x66, 0xe6,
0x48, 0x30, 0x83, 0xd5, 0x41, 0x79, 0x20, 0xf1, 0xe2, 0x92, 0xc4, 0x92, 0xd2, 0x62, 0x09, 0x16,
0x88, 0x38, 0x84, 0x97, 0xc4, 0x06, 0xb6, 0xcb, 0x18, 0x10, 0x00, 0x00, 0xff, 0xff, 0xca, 0xc3,
0xcb, 0x29, 0x82, 0x00, 0x00, 0x00,
func (x *MultiError) Reset() {
*x = MultiError{}
if protoimpl.UnsafeEnabled {
mi := &file_errors_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *MultiError) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*MultiError) ProtoMessage() {}
func (x *MultiError) ProtoReflect() protoreflect.Message {
mi := &file_errors_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use MultiError.ProtoReflect.Descriptor instead.
func (*MultiError) Descriptor() ([]byte, []int) {
return file_errors_proto_rawDescGZIP(), []int{1}
}
func (x *MultiError) GetErrors() []*Error {
if x != nil {
return x.Errors
}
return nil
}
var File_errors_proto protoreflect.FileDescriptor
var file_errors_proto_rawDesc = []byte{
0x0a, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06,
0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x22, 0x5b, 0x0a, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12,
0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12,
0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x63,
0x6f, 0x64, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x18, 0x03, 0x20,
0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x73,
0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61,
0x74, 0x75, 0x73, 0x22, 0x33, 0x0a, 0x0a, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x45, 0x72, 0x72, 0x6f,
0x72, 0x12, 0x25, 0x0a, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28,
0x0b, 0x32, 0x0d, 0x2e, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72,
0x52, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x42, 0x03, 0x5a, 0x01, 0x2e, 0x62, 0x06, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
file_errors_proto_rawDescOnce sync.Once
file_errors_proto_rawDescData = file_errors_proto_rawDesc
)
func file_errors_proto_rawDescGZIP() []byte {
file_errors_proto_rawDescOnce.Do(func() {
file_errors_proto_rawDescData = protoimpl.X.CompressGZIP(file_errors_proto_rawDescData)
})
return file_errors_proto_rawDescData
}
var file_errors_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
var file_errors_proto_goTypes = []interface{}{
(*Error)(nil), // 0: errors.Error
(*MultiError)(nil), // 1: errors.MultiError
}
var file_errors_proto_depIdxs = []int32{
0, // 0: errors.MultiError.errors:type_name -> errors.Error
1, // [1:1] is the sub-list for method output_type
1, // [1:1] is the sub-list for method input_type
1, // [1:1] is the sub-list for extension type_name
1, // [1:1] is the sub-list for extension extendee
0, // [0:1] is the sub-list for field type_name
}
func init() { file_errors_proto_init() }
func file_errors_proto_init() {
if File_errors_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_errors_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Error); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_errors_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*MultiError); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_errors_proto_rawDesc,
NumEnums: 0,
NumMessages: 2,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_errors_proto_goTypes,
DependencyIndexes: file_errors_proto_depIdxs,
MessageInfos: file_errors_proto_msgTypes,
}.Build()
File_errors_proto = out.File
file_errors_proto_rawDesc = nil
file_errors_proto_goTypes = nil
file_errors_proto_depIdxs = nil
}

View File

@ -1,11 +1,11 @@
// Code generated by protoc-gen-micro. DO NOT EDIT.
// source: errors/errors.proto
// source: errors.proto
package errors
import (
fmt "fmt"
proto "github.com/golang/protobuf/proto"
proto "google.golang.org/protobuf/proto"
math "math"
)
@ -13,9 +13,3 @@ import (
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package

View File

@ -8,3 +8,7 @@ message Error {
string detail = 3;
string status = 4;
};
message MultiError {
repeated Error errors = 1;
}

View File

@ -98,3 +98,81 @@ func TestAs(t *testing.T) {
t.Fatalf("nil should not convert to *Error")
}
}
func TestAppend(t *testing.T) {
mError := NewMultiError()
testData := []*Error{
{
Id: "test1",
Code: 500,
Detail: "Internal server error",
Status: http.StatusText(500),
},
{
Id: "test2",
Code: 400,
Detail: "Bad Request",
Status: http.StatusText(400),
},
{
Id: "test3",
Code: 404,
Detail: "Not Found",
Status: http.StatusText(404),
},
}
for _, e := range testData {
mError.Append(&Error{
Id: e.Id,
Code: e.Code,
Detail: e.Detail,
Status: e.Status,
})
}
if len(mError.Errors) != 3 {
t.Fatalf("Expected 3 got %v", len(mError.Errors))
}
}
func TestHasErrors(t *testing.T) {
mError := NewMultiError()
testData := []*Error{
{
Id: "test1",
Code: 500,
Detail: "Internal server error",
Status: http.StatusText(500),
},
{
Id: "test2",
Code: 400,
Detail: "Bad Request",
Status: http.StatusText(400),
},
{
Id: "test3",
Code: 404,
Detail: "Not Found",
Status: http.StatusText(404),
},
}
if mError.HasErrors() {
t.Fatal("Expected no error")
}
for _, e := range testData {
mError.Errors = append(mError.Errors, &Error{
Id: e.Id,
Code: e.Code,
Detail: e.Detail,
Status: e.Status,
})
}
if !mError.HasErrors() {
t.Fatal("Expected errors")
}
}

1
go.mod
View File

@ -28,4 +28,5 @@ require (
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a
golang.org/x/net v0.0.0-20210510120150-4163338589ed
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
google.golang.org/protobuf v1.26.0
)

1
go.sum
View File

@ -151,6 +151,7 @@ github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5Kwzbycv
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
github.com/felixge/httpsnoop v1.0.1 h1:lvB5Jl89CsZtGIWuTcDM1E/vkVs49/Ml7JJe07l8SPQ=
github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ=
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=