feat(cmd/protoc-gen-go-errors): additional field to generate ErrorWithFormat code

1. add Details message to errors.proto to allow adding more info to error
2. add optional format field to the Details message to generate the ErrorWithFormat function

Signed-off-by: HominSu <hominsu@foxmail.com>
pull/2776/head
HominSu 2 years ago committed by Homing So
parent 96480c11ee
commit fce113e7f7
No known key found for this signature in database
GPG Key ID: F8709F305B4186B3
  1. 16
      cmd/protoc-gen-go-errors/errors.go
  2. 137
      cmd/protoc-gen-go-errors/errors/errors.pb.go
  3. 5
      cmd/protoc-gen-go-errors/errors/errors.proto
  4. 13
      cmd/protoc-gen-go-errors/errorsTemplate.tpl
  5. 7
      cmd/protoc-gen-go-errors/template.go
  6. 5
      third_party/errors/errors.proto

@ -89,6 +89,12 @@ func genErrorsReason(_ *protogen.Plugin, _ *protogen.File, g *protogen.Generated
comment = v.Comments.Trailing.String()
}
var enumDetails *errorDetails
eDetails := proto.GetExtension(v.Desc.Options(), errors.E_Details)
if d := eDetails.(*errors.Details); d != nil {
enumDetails = getDetails(d)
}
err := &errorInfo{
Name: string(enum.Desc.Name()),
Value: string(v.Desc.Name()),
@ -96,6 +102,8 @@ func genErrorsReason(_ *protogen.Plugin, _ *protogen.File, g *protogen.Generated
HTTPCode: enumCode,
Comment: comment,
HasComment: len(comment) > 0,
Details: enumDetails,
HasDetails: enumDetails != nil,
}
ew.Errors = append(ew.Errors, err)
}
@ -107,6 +115,14 @@ func genErrorsReason(_ *protogen.Plugin, _ *protogen.File, g *protogen.Generated
return false
}
func getDetails(d *errors.Details) *errorDetails {
details := &errorDetails{
Format: d.GetFormat(),
HasFormat: d.Format != nil,
}
return details
}
func case2Camel(name string) string {
if !strings.Contains(name, "_") {
if name == strings.ToUpper(name) {

@ -92,6 +92,53 @@ func (x *Error) GetMetadata() map[string]string {
return nil
}
type Details struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Format *string `protobuf:"bytes,1,opt,name=format,proto3,oneof" json:"format,omitempty"`
}
func (x *Details) Reset() {
*x = Details{}
if protoimpl.UnsafeEnabled {
mi := &file_errors_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Details) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Details) ProtoMessage() {}
func (x *Details) 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 Details.ProtoReflect.Descriptor instead.
func (*Details) Descriptor() ([]byte, []int) {
return file_errors_proto_rawDescGZIP(), []int{1}
}
func (x *Details) GetFormat() string {
if x != nil && x.Format != nil {
return *x.Format
}
return ""
}
var file_errors_proto_extTypes = []protoimpl.ExtensionInfo{
{
ExtendedType: (*descriptorpb.EnumOptions)(nil),
@ -109,6 +156,14 @@ var file_errors_proto_extTypes = []protoimpl.ExtensionInfo{
Tag: "varint,1109,opt,name=code",
Filename: "errors.proto",
},
{
ExtendedType: (*descriptorpb.EnumValueOptions)(nil),
ExtensionType: (*Details)(nil),
Field: 1110,
Name: "errors.details",
Tag: "bytes,1110,opt,name=details",
Filename: "errors.proto",
},
}
// Extension fields to descriptorpb.EnumOptions.
@ -121,6 +176,8 @@ var (
var (
// optional int32 code = 1109;
E_Code = &file_errors_proto_extTypes[1]
// optional errors.Details details = 1110;
E_Details = &file_errors_proto_extTypes[2]
)
var File_errors_proto protoreflect.FileDescriptor
@ -141,21 +198,29 @@ var file_errors_proto_rawDesc = []byte{
0x61, 0x1a, 0x3b, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74,
0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20,
0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x3a, 0x40,
0x0a, 0x0c, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x1c,
0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
0x2e, 0x45, 0x6e, 0x75, 0x6d, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xd4, 0x08, 0x20,
0x01, 0x28, 0x05, 0x52, 0x0b, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x43, 0x6f, 0x64, 0x65,
0x3a, 0x36, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x21, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6e, 0x75, 0x6d, 0x56,
0x61, 0x6c, 0x75, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xd5, 0x08, 0x20, 0x01,
0x28, 0x05, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x42, 0x59, 0x0a, 0x18, 0x63, 0x6f, 0x6d, 0x2e,
0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2e, 0x65, 0x72,
0x72, 0x6f, 0x72, 0x73, 0x50, 0x01, 0x5a, 0x2c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63,
0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x2d, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2f, 0x6b, 0x72, 0x61,
0x74, 0x6f, 0x73, 0x2f, 0x76, 0x32, 0x2f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x3b, 0x65, 0x72,
0x72, 0x6f, 0x72, 0x73, 0xa2, 0x02, 0x0c, 0x4b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x45, 0x72, 0x72,
0x6f, 0x72, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x31,
0x0a, 0x07, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x1b, 0x0a, 0x06, 0x66, 0x6f, 0x72,
0x6d, 0x61, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x06, 0x66, 0x6f, 0x72,
0x6d, 0x61, 0x74, 0x88, 0x01, 0x01, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61,
0x74, 0x3a, 0x40, 0x0a, 0x0c, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x63, 0x6f, 0x64,
0x65, 0x12, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x62, 0x75, 0x66, 0x2e, 0x45, 0x6e, 0x75, 0x6d, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18,
0xd4, 0x08, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x43,
0x6f, 0x64, 0x65, 0x3a, 0x36, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x21, 0x2e, 0x67, 0x6f,
0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6e,
0x75, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xd5,
0x08, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x3a, 0x50, 0x0a, 0x07, 0x64,
0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x21, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6e, 0x75, 0x6d, 0x56, 0x61, 0x6c,
0x75, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xd6, 0x08, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x0f, 0x2e, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x2e, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c,
0x73, 0x52, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x88, 0x01, 0x01, 0x42, 0x59, 0x0a,
0x18, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x6b, 0x72, 0x61, 0x74,
0x6f, 0x73, 0x2e, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x50, 0x01, 0x5a, 0x2c, 0x67, 0x69, 0x74,
0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x2d, 0x6b, 0x72, 0x61, 0x74, 0x6f,
0x73, 0x2f, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2f, 0x76, 0x32, 0x2f, 0x65, 0x72, 0x72, 0x6f,
0x72, 0x73, 0x3b, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0xa2, 0x02, 0x0c, 0x4b, 0x72, 0x61, 0x74,
0x6f, 0x73, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@ -170,21 +235,24 @@ func file_errors_proto_rawDescGZIP() []byte {
return file_errors_proto_rawDescData
}
var file_errors_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
var file_errors_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
var file_errors_proto_goTypes = []interface{}{
(*Error)(nil), // 0: errors.Error
nil, // 1: errors.Error.MetadataEntry
(*descriptorpb.EnumOptions)(nil), // 2: google.protobuf.EnumOptions
(*descriptorpb.EnumValueOptions)(nil), // 3: google.protobuf.EnumValueOptions
(*Details)(nil), // 1: errors.Details
nil, // 2: errors.Error.MetadataEntry
(*descriptorpb.EnumOptions)(nil), // 3: google.protobuf.EnumOptions
(*descriptorpb.EnumValueOptions)(nil), // 4: google.protobuf.EnumValueOptions
}
var file_errors_proto_depIdxs = []int32{
1, // 0: errors.Error.metadata:type_name -> errors.Error.MetadataEntry
2, // 1: errors.default_code:extendee -> google.protobuf.EnumOptions
3, // 2: errors.code:extendee -> google.protobuf.EnumValueOptions
3, // [3:3] is the sub-list for method output_type
3, // [3:3] is the sub-list for method input_type
3, // [3:3] is the sub-list for extension type_name
1, // [1:3] is the sub-list for extension extendee
2, // 0: errors.Error.metadata:type_name -> errors.Error.MetadataEntry
3, // 1: errors.default_code:extendee -> google.protobuf.EnumOptions
4, // 2: errors.code:extendee -> google.protobuf.EnumValueOptions
4, // 3: errors.details:extendee -> google.protobuf.EnumValueOptions
1, // 4: errors.details:type_name -> errors.Details
5, // [5:5] is the sub-list for method output_type
5, // [5:5] is the sub-list for method input_type
4, // [4:5] is the sub-list for extension type_name
1, // [1:4] is the sub-list for extension extendee
0, // [0:1] is the sub-list for field type_name
}
@ -206,15 +274,28 @@ func file_errors_proto_init() {
return nil
}
}
file_errors_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Details); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
file_errors_proto_msgTypes[1].OneofWrappers = []interface{}{}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_errors_proto_rawDesc,
NumEnums: 0,
NumMessages: 2,
NumExtensions: 2,
NumMessages: 3,
NumExtensions: 3,
NumServices: 0,
},
GoTypes: file_errors_proto_goTypes,

@ -22,4 +22,9 @@ extend google.protobuf.EnumOptions {
extend google.protobuf.EnumValueOptions {
int32 code = 1109;
optional Details details = 1110;
}
message Details {
optional string format = 1;
}

@ -14,4 +14,17 @@ func Error{{ .CamelValue }}(format string, args ...interface{}) *errors.Error {
return errors.New({{ .HTTPCode }}, {{ .Name }}_{{ .Value }}.String(), fmt.Sprintf(format, args...))
}
{{ if .HasDetails }}
{{ if .Details.HasFormat }}
{{ if .HasComment }}{{ .Comment }}{{ end -}}
func Error{{ .CamelValue }}WithFormat(args ...interface{}) *errors.Error {
return errors.New({{ .HTTPCode }}, {{ .Name }}_{{ .Value }}.String(), fmt.Sprintf("{{ .Details.Format }}", args...))
}
{{- end }}
{{- end }}
{{- end }}

@ -16,6 +16,13 @@ type errorInfo struct {
CamelValue string
Comment string
HasComment bool
Details *errorDetails
HasDetails bool
}
type errorDetails struct {
Format string
HasFormat bool
}
type errorWrapper struct {

@ -15,4 +15,9 @@ extend google.protobuf.EnumOptions {
extend google.protobuf.EnumValueOptions {
int32 code = 1109;
optional Details details = 1110;
}
message Details {
optional string format = 1;
}

Loading…
Cancel
Save