diff --git a/modules/openapi-generator/src/main/resources/go/client.mustache b/modules/openapi-generator/src/main/resources/go/client.mustache index c0fea7cafc3d..8f8b4b69766f 100644 --- a/modules/openapi-generator/src/main/resources/go/client.mustache +++ b/modules/openapi-generator/src/main/resources/go/client.mustache @@ -753,20 +753,51 @@ func (e GenericOpenAPIError) Model() interface{} { // format error message using title and detail when model implements rfc7807 func formatErrorMessage(status string, v interface{}) string { - str := "" - metaValue := reflect.ValueOf(v).Elem() + title := rfc7807Field(v, "Title") + detail := rfc7807Field(v, "Detail") + + var str string + switch { + case title != "" && detail != "": + str = title + " (" + detail + ")" + case title != "": + str = title + default: + str = detail + } + + return strings.TrimSpace(status + " " + str) +} - if metaValue.Kind() == reflect.Struct { - field := metaValue.FieldByName("Title") - if field != (reflect.Value{}) { - str = fmt.Sprintf("%s", field.Interface()) +// rfc7807Field reads a string member of an rfc7807 model, following one level of pointer +// indirection so that an optional field declared as *string yields its value rather than its +// address. It returns the empty string when the member is absent, is a nil pointer, or holds the +// empty string, so a member that was not set contributes nothing to the message. +func rfc7807Field(v interface{}, name string) string { + value := reflect.ValueOf(v) + if value.Kind() == reflect.Pointer { + if value.IsNil() { + return "" } + value = value.Elem() + } + if value.Kind() != reflect.Struct { + return "" + } - field = metaValue.FieldByName("Detail") - if field != (reflect.Value{}) { - str = fmt.Sprintf("%s (%s)", str, field.Interface()) + field := value.FieldByName(name) + if !field.IsValid() { + return "" + } + if field.Kind() == reflect.Pointer { + if field.IsNil() { + return "" } + field = field.Elem() + } + if field.Kind() != reflect.String { + return "" } - return strings.TrimSpace(fmt.Sprintf("%s %s", status, str)) + return field.String() } diff --git a/samples/client/echo_api/go-external-refs/client.go b/samples/client/echo_api/go-external-refs/client.go index 83d93205607b..5575e9bccbc9 100644 --- a/samples/client/echo_api/go-external-refs/client.go +++ b/samples/client/echo_api/go-external-refs/client.go @@ -669,20 +669,51 @@ func (e GenericOpenAPIError) Model() interface{} { // format error message using title and detail when model implements rfc7807 func formatErrorMessage(status string, v interface{}) string { - str := "" - metaValue := reflect.ValueOf(v).Elem() + title := rfc7807Field(v, "Title") + detail := rfc7807Field(v, "Detail") + + var str string + switch { + case title != "" && detail != "": + str = title + " (" + detail + ")" + case title != "": + str = title + default: + str = detail + } + + return strings.TrimSpace(status + " " + str) +} - if metaValue.Kind() == reflect.Struct { - field := metaValue.FieldByName("Title") - if field != (reflect.Value{}) { - str = fmt.Sprintf("%s", field.Interface()) +// rfc7807Field reads a string member of an rfc7807 model, following one level of pointer +// indirection so that an optional field declared as *string yields its value rather than its +// address. It returns the empty string when the member is absent, is a nil pointer, or holds the +// empty string, so a member that was not set contributes nothing to the message. +func rfc7807Field(v interface{}, name string) string { + value := reflect.ValueOf(v) + if value.Kind() == reflect.Pointer { + if value.IsNil() { + return "" } + value = value.Elem() + } + if value.Kind() != reflect.Struct { + return "" + } - field = metaValue.FieldByName("Detail") - if field != (reflect.Value{}) { - str = fmt.Sprintf("%s (%s)", str, field.Interface()) + field := value.FieldByName(name) + if !field.IsValid() { + return "" + } + if field.Kind() == reflect.Pointer { + if field.IsNil() { + return "" } + field = field.Elem() + } + if field.Kind() != reflect.String { + return "" } - return strings.TrimSpace(fmt.Sprintf("%s %s", status, str)) + return field.String() } diff --git a/samples/client/echo_api/go/client.go b/samples/client/echo_api/go/client.go index 83d93205607b..5575e9bccbc9 100644 --- a/samples/client/echo_api/go/client.go +++ b/samples/client/echo_api/go/client.go @@ -669,20 +669,51 @@ func (e GenericOpenAPIError) Model() interface{} { // format error message using title and detail when model implements rfc7807 func formatErrorMessage(status string, v interface{}) string { - str := "" - metaValue := reflect.ValueOf(v).Elem() + title := rfc7807Field(v, "Title") + detail := rfc7807Field(v, "Detail") + + var str string + switch { + case title != "" && detail != "": + str = title + " (" + detail + ")" + case title != "": + str = title + default: + str = detail + } + + return strings.TrimSpace(status + " " + str) +} - if metaValue.Kind() == reflect.Struct { - field := metaValue.FieldByName("Title") - if field != (reflect.Value{}) { - str = fmt.Sprintf("%s", field.Interface()) +// rfc7807Field reads a string member of an rfc7807 model, following one level of pointer +// indirection so that an optional field declared as *string yields its value rather than its +// address. It returns the empty string when the member is absent, is a nil pointer, or holds the +// empty string, so a member that was not set contributes nothing to the message. +func rfc7807Field(v interface{}, name string) string { + value := reflect.ValueOf(v) + if value.Kind() == reflect.Pointer { + if value.IsNil() { + return "" } + value = value.Elem() + } + if value.Kind() != reflect.Struct { + return "" + } - field = metaValue.FieldByName("Detail") - if field != (reflect.Value{}) { - str = fmt.Sprintf("%s (%s)", str, field.Interface()) + field := value.FieldByName(name) + if !field.IsValid() { + return "" + } + if field.Kind() == reflect.Pointer { + if field.IsNil() { + return "" } + field = field.Elem() + } + if field.Kind() != reflect.String { + return "" } - return strings.TrimSpace(fmt.Sprintf("%s %s", status, str)) + return field.String() } diff --git a/samples/client/others/go/allof_multiple_ref_and_discriminator/client.go b/samples/client/others/go/allof_multiple_ref_and_discriminator/client.go index 7a19a74088d8..4ad15f47dd02 100644 --- a/samples/client/others/go/allof_multiple_ref_and_discriminator/client.go +++ b/samples/client/others/go/allof_multiple_ref_and_discriminator/client.go @@ -640,20 +640,51 @@ func (e GenericOpenAPIError) Model() interface{} { // format error message using title and detail when model implements rfc7807 func formatErrorMessage(status string, v interface{}) string { - str := "" - metaValue := reflect.ValueOf(v).Elem() + title := rfc7807Field(v, "Title") + detail := rfc7807Field(v, "Detail") + + var str string + switch { + case title != "" && detail != "": + str = title + " (" + detail + ")" + case title != "": + str = title + default: + str = detail + } + + return strings.TrimSpace(status + " " + str) +} - if metaValue.Kind() == reflect.Struct { - field := metaValue.FieldByName("Title") - if field != (reflect.Value{}) { - str = fmt.Sprintf("%s", field.Interface()) +// rfc7807Field reads a string member of an rfc7807 model, following one level of pointer +// indirection so that an optional field declared as *string yields its value rather than its +// address. It returns the empty string when the member is absent, is a nil pointer, or holds the +// empty string, so a member that was not set contributes nothing to the message. +func rfc7807Field(v interface{}, name string) string { + value := reflect.ValueOf(v) + if value.Kind() == reflect.Pointer { + if value.IsNil() { + return "" } + value = value.Elem() + } + if value.Kind() != reflect.Struct { + return "" + } - field = metaValue.FieldByName("Detail") - if field != (reflect.Value{}) { - str = fmt.Sprintf("%s (%s)", str, field.Interface()) + field := value.FieldByName(name) + if !field.IsValid() { + return "" + } + if field.Kind() == reflect.Pointer { + if field.IsNil() { + return "" } + field = field.Elem() + } + if field.Kind() != reflect.String { + return "" } - return strings.TrimSpace(fmt.Sprintf("%s %s", status, str)) + return field.String() } diff --git a/samples/client/others/go/issue_20079_go_regex_wrongly_translated/client.go b/samples/client/others/go/issue_20079_go_regex_wrongly_translated/client.go index b681437f098b..2611609bffca 100644 --- a/samples/client/others/go/issue_20079_go_regex_wrongly_translated/client.go +++ b/samples/client/others/go/issue_20079_go_regex_wrongly_translated/client.go @@ -643,20 +643,51 @@ func (e GenericOpenAPIError) Model() interface{} { // format error message using title and detail when model implements rfc7807 func formatErrorMessage(status string, v interface{}) string { - str := "" - metaValue := reflect.ValueOf(v).Elem() + title := rfc7807Field(v, "Title") + detail := rfc7807Field(v, "Detail") + + var str string + switch { + case title != "" && detail != "": + str = title + " (" + detail + ")" + case title != "": + str = title + default: + str = detail + } + + return strings.TrimSpace(status + " " + str) +} - if metaValue.Kind() == reflect.Struct { - field := metaValue.FieldByName("Title") - if field != (reflect.Value{}) { - str = fmt.Sprintf("%s", field.Interface()) +// rfc7807Field reads a string member of an rfc7807 model, following one level of pointer +// indirection so that an optional field declared as *string yields its value rather than its +// address. It returns the empty string when the member is absent, is a nil pointer, or holds the +// empty string, so a member that was not set contributes nothing to the message. +func rfc7807Field(v interface{}, name string) string { + value := reflect.ValueOf(v) + if value.Kind() == reflect.Pointer { + if value.IsNil() { + return "" } + value = value.Elem() + } + if value.Kind() != reflect.Struct { + return "" + } - field = metaValue.FieldByName("Detail") - if field != (reflect.Value{}) { - str = fmt.Sprintf("%s (%s)", str, field.Interface()) + field := value.FieldByName(name) + if !field.IsValid() { + return "" + } + if field.Kind() == reflect.Pointer { + if field.IsNil() { + return "" } + field = field.Elem() + } + if field.Kind() != reflect.String { + return "" } - return strings.TrimSpace(fmt.Sprintf("%s %s", status, str)) + return field.String() } diff --git a/samples/client/others/go/oneof-anyof-required/client.go b/samples/client/others/go/oneof-anyof-required/client.go index 7a19a74088d8..4ad15f47dd02 100644 --- a/samples/client/others/go/oneof-anyof-required/client.go +++ b/samples/client/others/go/oneof-anyof-required/client.go @@ -640,20 +640,51 @@ func (e GenericOpenAPIError) Model() interface{} { // format error message using title and detail when model implements rfc7807 func formatErrorMessage(status string, v interface{}) string { - str := "" - metaValue := reflect.ValueOf(v).Elem() + title := rfc7807Field(v, "Title") + detail := rfc7807Field(v, "Detail") + + var str string + switch { + case title != "" && detail != "": + str = title + " (" + detail + ")" + case title != "": + str = title + default: + str = detail + } + + return strings.TrimSpace(status + " " + str) +} - if metaValue.Kind() == reflect.Struct { - field := metaValue.FieldByName("Title") - if field != (reflect.Value{}) { - str = fmt.Sprintf("%s", field.Interface()) +// rfc7807Field reads a string member of an rfc7807 model, following one level of pointer +// indirection so that an optional field declared as *string yields its value rather than its +// address. It returns the empty string when the member is absent, is a nil pointer, or holds the +// empty string, so a member that was not set contributes nothing to the message. +func rfc7807Field(v interface{}, name string) string { + value := reflect.ValueOf(v) + if value.Kind() == reflect.Pointer { + if value.IsNil() { + return "" } + value = value.Elem() + } + if value.Kind() != reflect.Struct { + return "" + } - field = metaValue.FieldByName("Detail") - if field != (reflect.Value{}) { - str = fmt.Sprintf("%s (%s)", str, field.Interface()) + field := value.FieldByName(name) + if !field.IsValid() { + return "" + } + if field.Kind() == reflect.Pointer { + if field.IsNil() { + return "" } + field = field.Elem() + } + if field.Kind() != reflect.String { + return "" } - return strings.TrimSpace(fmt.Sprintf("%s %s", status, str)) + return field.String() } diff --git a/samples/client/others/go/oneof-discriminator-lookup/client.go b/samples/client/others/go/oneof-discriminator-lookup/client.go index 7a19a74088d8..4ad15f47dd02 100644 --- a/samples/client/others/go/oneof-discriminator-lookup/client.go +++ b/samples/client/others/go/oneof-discriminator-lookup/client.go @@ -640,20 +640,51 @@ func (e GenericOpenAPIError) Model() interface{} { // format error message using title and detail when model implements rfc7807 func formatErrorMessage(status string, v interface{}) string { - str := "" - metaValue := reflect.ValueOf(v).Elem() + title := rfc7807Field(v, "Title") + detail := rfc7807Field(v, "Detail") + + var str string + switch { + case title != "" && detail != "": + str = title + " (" + detail + ")" + case title != "": + str = title + default: + str = detail + } + + return strings.TrimSpace(status + " " + str) +} - if metaValue.Kind() == reflect.Struct { - field := metaValue.FieldByName("Title") - if field != (reflect.Value{}) { - str = fmt.Sprintf("%s", field.Interface()) +// rfc7807Field reads a string member of an rfc7807 model, following one level of pointer +// indirection so that an optional field declared as *string yields its value rather than its +// address. It returns the empty string when the member is absent, is a nil pointer, or holds the +// empty string, so a member that was not set contributes nothing to the message. +func rfc7807Field(v interface{}, name string) string { + value := reflect.ValueOf(v) + if value.Kind() == reflect.Pointer { + if value.IsNil() { + return "" } + value = value.Elem() + } + if value.Kind() != reflect.Struct { + return "" + } - field = metaValue.FieldByName("Detail") - if field != (reflect.Value{}) { - str = fmt.Sprintf("%s (%s)", str, field.Interface()) + field := value.FieldByName(name) + if !field.IsValid() { + return "" + } + if field.Kind() == reflect.Pointer { + if field.IsNil() { + return "" } + field = field.Elem() + } + if field.Kind() != reflect.String { + return "" } - return strings.TrimSpace(fmt.Sprintf("%s %s", status, str)) + return field.String() } diff --git a/samples/client/petstore/go/go-petstore/client.go b/samples/client/petstore/go/go-petstore/client.go index 85036942f54b..462f51fc05d6 100644 --- a/samples/client/petstore/go/go-petstore/client.go +++ b/samples/client/petstore/go/go-petstore/client.go @@ -675,20 +675,51 @@ func (e GenericOpenAPIError) Model() interface{} { // format error message using title and detail when model implements rfc7807 func formatErrorMessage(status string, v interface{}) string { - str := "" - metaValue := reflect.ValueOf(v).Elem() + title := rfc7807Field(v, "Title") + detail := rfc7807Field(v, "Detail") + + var str string + switch { + case title != "" && detail != "": + str = title + " (" + detail + ")" + case title != "": + str = title + default: + str = detail + } + + return strings.TrimSpace(status + " " + str) +} - if metaValue.Kind() == reflect.Struct { - field := metaValue.FieldByName("Title") - if field != (reflect.Value{}) { - str = fmt.Sprintf("%s", field.Interface()) +// rfc7807Field reads a string member of an rfc7807 model, following one level of pointer +// indirection so that an optional field declared as *string yields its value rather than its +// address. It returns the empty string when the member is absent, is a nil pointer, or holds the +// empty string, so a member that was not set contributes nothing to the message. +func rfc7807Field(v interface{}, name string) string { + value := reflect.ValueOf(v) + if value.Kind() == reflect.Pointer { + if value.IsNil() { + return "" } + value = value.Elem() + } + if value.Kind() != reflect.Struct { + return "" + } - field = metaValue.FieldByName("Detail") - if field != (reflect.Value{}) { - str = fmt.Sprintf("%s (%s)", str, field.Interface()) + field := value.FieldByName(name) + if !field.IsValid() { + return "" + } + if field.Kind() == reflect.Pointer { + if field.IsNil() { + return "" } + field = field.Elem() + } + if field.Kind() != reflect.String { + return "" } - return strings.TrimSpace(fmt.Sprintf("%s %s", status, str)) + return field.String() } diff --git a/samples/openapi3/client/extensions/x-auth-id-alias/go-experimental/client.go b/samples/openapi3/client/extensions/x-auth-id-alias/go-experimental/client.go index 58b26ebc1573..abfa1b852404 100644 --- a/samples/openapi3/client/extensions/x-auth-id-alias/go-experimental/client.go +++ b/samples/openapi3/client/extensions/x-auth-id-alias/go-experimental/client.go @@ -643,20 +643,51 @@ func (e GenericOpenAPIError) Model() interface{} { // format error message using title and detail when model implements rfc7807 func formatErrorMessage(status string, v interface{}) string { - str := "" - metaValue := reflect.ValueOf(v).Elem() + title := rfc7807Field(v, "Title") + detail := rfc7807Field(v, "Detail") + + var str string + switch { + case title != "" && detail != "": + str = title + " (" + detail + ")" + case title != "": + str = title + default: + str = detail + } + + return strings.TrimSpace(status + " " + str) +} - if metaValue.Kind() == reflect.Struct { - field := metaValue.FieldByName("Title") - if field != (reflect.Value{}) { - str = fmt.Sprintf("%s", field.Interface()) +// rfc7807Field reads a string member of an rfc7807 model, following one level of pointer +// indirection so that an optional field declared as *string yields its value rather than its +// address. It returns the empty string when the member is absent, is a nil pointer, or holds the +// empty string, so a member that was not set contributes nothing to the message. +func rfc7807Field(v interface{}, name string) string { + value := reflect.ValueOf(v) + if value.Kind() == reflect.Pointer { + if value.IsNil() { + return "" } + value = value.Elem() + } + if value.Kind() != reflect.Struct { + return "" + } - field = metaValue.FieldByName("Detail") - if field != (reflect.Value{}) { - str = fmt.Sprintf("%s (%s)", str, field.Interface()) + field := value.FieldByName(name) + if !field.IsValid() { + return "" + } + if field.Kind() == reflect.Pointer { + if field.IsNil() { + return "" } + field = field.Elem() + } + if field.Kind() != reflect.String { + return "" } - return strings.TrimSpace(fmt.Sprintf("%s %s", status, str)) + return field.String() } diff --git a/samples/openapi3/client/petstore/go-petstore-generateMarshalJSON-false/client.go b/samples/openapi3/client/petstore/go-petstore-generateMarshalJSON-false/client.go index 7f611c52fa4d..509373a8f51e 100644 --- a/samples/openapi3/client/petstore/go-petstore-generateMarshalJSON-false/client.go +++ b/samples/openapi3/client/petstore/go-petstore-generateMarshalJSON-false/client.go @@ -655,20 +655,51 @@ func (e GenericOpenAPIError) Model() interface{} { // format error message using title and detail when model implements rfc7807 func formatErrorMessage(status string, v interface{}) string { - str := "" - metaValue := reflect.ValueOf(v).Elem() + title := rfc7807Field(v, "Title") + detail := rfc7807Field(v, "Detail") + + var str string + switch { + case title != "" && detail != "": + str = title + " (" + detail + ")" + case title != "": + str = title + default: + str = detail + } + + return strings.TrimSpace(status + " " + str) +} - if metaValue.Kind() == reflect.Struct { - field := metaValue.FieldByName("Title") - if field != (reflect.Value{}) { - str = fmt.Sprintf("%s", field.Interface()) +// rfc7807Field reads a string member of an rfc7807 model, following one level of pointer +// indirection so that an optional field declared as *string yields its value rather than its +// address. It returns the empty string when the member is absent, is a nil pointer, or holds the +// empty string, so a member that was not set contributes nothing to the message. +func rfc7807Field(v interface{}, name string) string { + value := reflect.ValueOf(v) + if value.Kind() == reflect.Pointer { + if value.IsNil() { + return "" } + value = value.Elem() + } + if value.Kind() != reflect.Struct { + return "" + } - field = metaValue.FieldByName("Detail") - if field != (reflect.Value{}) { - str = fmt.Sprintf("%s (%s)", str, field.Interface()) + field := value.FieldByName(name) + if !field.IsValid() { + return "" + } + if field.Kind() == reflect.Pointer { + if field.IsNil() { + return "" } + field = field.Elem() + } + if field.Kind() != reflect.String { + return "" } - return strings.TrimSpace(fmt.Sprintf("%s %s", status, str)) + return field.String() } diff --git a/samples/openapi3/client/petstore/go-petstore-withXml/client.go b/samples/openapi3/client/petstore/go-petstore-withXml/client.go index 7f611c52fa4d..509373a8f51e 100644 --- a/samples/openapi3/client/petstore/go-petstore-withXml/client.go +++ b/samples/openapi3/client/petstore/go-petstore-withXml/client.go @@ -655,20 +655,51 @@ func (e GenericOpenAPIError) Model() interface{} { // format error message using title and detail when model implements rfc7807 func formatErrorMessage(status string, v interface{}) string { - str := "" - metaValue := reflect.ValueOf(v).Elem() + title := rfc7807Field(v, "Title") + detail := rfc7807Field(v, "Detail") + + var str string + switch { + case title != "" && detail != "": + str = title + " (" + detail + ")" + case title != "": + str = title + default: + str = detail + } + + return strings.TrimSpace(status + " " + str) +} - if metaValue.Kind() == reflect.Struct { - field := metaValue.FieldByName("Title") - if field != (reflect.Value{}) { - str = fmt.Sprintf("%s", field.Interface()) +// rfc7807Field reads a string member of an rfc7807 model, following one level of pointer +// indirection so that an optional field declared as *string yields its value rather than its +// address. It returns the empty string when the member is absent, is a nil pointer, or holds the +// empty string, so a member that was not set contributes nothing to the message. +func rfc7807Field(v interface{}, name string) string { + value := reflect.ValueOf(v) + if value.Kind() == reflect.Pointer { + if value.IsNil() { + return "" } + value = value.Elem() + } + if value.Kind() != reflect.Struct { + return "" + } - field = metaValue.FieldByName("Detail") - if field != (reflect.Value{}) { - str = fmt.Sprintf("%s (%s)", str, field.Interface()) + field := value.FieldByName(name) + if !field.IsValid() { + return "" + } + if field.Kind() == reflect.Pointer { + if field.IsNil() { + return "" } + field = field.Elem() + } + if field.Kind() != reflect.String { + return "" } - return strings.TrimSpace(fmt.Sprintf("%s %s", status, str)) + return field.String() } diff --git a/samples/openapi3/client/petstore/go/go-petstore-aws-signature/client.go b/samples/openapi3/client/petstore/go/go-petstore-aws-signature/client.go index 73c66a0e3188..b4d1531b3348 100644 --- a/samples/openapi3/client/petstore/go/go-petstore-aws-signature/client.go +++ b/samples/openapi3/client/petstore/go/go-petstore-aws-signature/client.go @@ -697,20 +697,51 @@ func (e GenericOpenAPIError) Model() interface{} { // format error message using title and detail when model implements rfc7807 func formatErrorMessage(status string, v interface{}) string { - str := "" - metaValue := reflect.ValueOf(v).Elem() + title := rfc7807Field(v, "Title") + detail := rfc7807Field(v, "Detail") + + var str string + switch { + case title != "" && detail != "": + str = title + " (" + detail + ")" + case title != "": + str = title + default: + str = detail + } + + return strings.TrimSpace(status + " " + str) +} - if metaValue.Kind() == reflect.Struct { - field := metaValue.FieldByName("Title") - if field != (reflect.Value{}) { - str = fmt.Sprintf("%s", field.Interface()) +// rfc7807Field reads a string member of an rfc7807 model, following one level of pointer +// indirection so that an optional field declared as *string yields its value rather than its +// address. It returns the empty string when the member is absent, is a nil pointer, or holds the +// empty string, so a member that was not set contributes nothing to the message. +func rfc7807Field(v interface{}, name string) string { + value := reflect.ValueOf(v) + if value.Kind() == reflect.Pointer { + if value.IsNil() { + return "" } + value = value.Elem() + } + if value.Kind() != reflect.Struct { + return "" + } - field = metaValue.FieldByName("Detail") - if field != (reflect.Value{}) { - str = fmt.Sprintf("%s (%s)", str, field.Interface()) + field := value.FieldByName(name) + if !field.IsValid() { + return "" + } + if field.Kind() == reflect.Pointer { + if field.IsNil() { + return "" } + field = field.Elem() + } + if field.Kind() != reflect.String { + return "" } - return strings.TrimSpace(fmt.Sprintf("%s %s", status, str)) + return field.String() } diff --git a/samples/openapi3/client/petstore/go/go-petstore/client.go b/samples/openapi3/client/petstore/go/go-petstore/client.go index 8f341a904a36..efa5216f451f 100644 --- a/samples/openapi3/client/petstore/go/go-petstore/client.go +++ b/samples/openapi3/client/petstore/go/go-petstore/client.go @@ -693,20 +693,51 @@ func (e GenericOpenAPIError) Model() interface{} { // format error message using title and detail when model implements rfc7807 func formatErrorMessage(status string, v interface{}) string { - str := "" - metaValue := reflect.ValueOf(v).Elem() + title := rfc7807Field(v, "Title") + detail := rfc7807Field(v, "Detail") + + var str string + switch { + case title != "" && detail != "": + str = title + " (" + detail + ")" + case title != "": + str = title + default: + str = detail + } + + return strings.TrimSpace(status + " " + str) +} - if metaValue.Kind() == reflect.Struct { - field := metaValue.FieldByName("Title") - if field != (reflect.Value{}) { - str = fmt.Sprintf("%s", field.Interface()) +// rfc7807Field reads a string member of an rfc7807 model, following one level of pointer +// indirection so that an optional field declared as *string yields its value rather than its +// address. It returns the empty string when the member is absent, is a nil pointer, or holds the +// empty string, so a member that was not set contributes nothing to the message. +func rfc7807Field(v interface{}, name string) string { + value := reflect.ValueOf(v) + if value.Kind() == reflect.Pointer { + if value.IsNil() { + return "" } + value = value.Elem() + } + if value.Kind() != reflect.Struct { + return "" + } - field = metaValue.FieldByName("Detail") - if field != (reflect.Value{}) { - str = fmt.Sprintf("%s (%s)", str, field.Interface()) + field := value.FieldByName(name) + if !field.IsValid() { + return "" + } + if field.Kind() == reflect.Pointer { + if field.IsNil() { + return "" } + field = field.Elem() + } + if field.Kind() != reflect.String { + return "" } - return strings.TrimSpace(fmt.Sprintf("%s %s", status, str)) + return field.String() }