package errors import ( "strings" "github.com/gin-gonic/gin" "github.com/go-playground/validator/v10" ) var ( ReadOnlyFieldMessage = "is read-only" RequiredFieldMessage = "is required" InvalidRFC1123HostnameMessage = "must be a valid RFC 1123 Hostname" ) // NewErrorResponse returns a new gin API error response func NewErrorResponse(errors ...*Error) gin.H { return gin.H{ "errors": errors, } } // Error represents an individual error returned by the API // // swagger:model type Error struct { // A description of the error // // required: true // example: X is a read-only field Detail string `json:"detail"` } // NewError returns a new error struct containing the provided detail func NewError(detail string) *Error { return &Error{ Detail: detail, } } // String returns the errors internal detail string func (e *Error) String() string { return e.Detail } // FromFieldError sets the error detail from the provided field error func (e *Error) FromFieldError(fe validator.FieldError) { e.Detail = NewFieldErrorDetail(fe) } // NewFieldErrorDetail returns an error detail message appropriate for the // provided field error func NewFieldErrorDetail(fe validator.FieldError) string { switch fe.Tag() { case "required": return NewRequiredFieldMessage(fe.Field()) case "hostname_rfc1123": return NewInvalidRFC1123HostnameMessage(fe.Field()) } return fe.Error() } // NewReadOnlyFieldMessage returns a new read-only field error detail string for // the provided field func NewReadOnlyFieldMessage(field string) string { return NewMessage(field, ReadOnlyFieldMessage) } // NewRequiredFieldMessage returns a new required field error detail string for // the provided field func NewRequiredFieldMessage(field string) string { return NewMessage(field, RequiredFieldMessage) } // NewValidRFC1123HostnameMessage returns a new invalid RFC1123 hostname field // error detail string for the provided field func NewInvalidRFC1123HostnameMessage(field string) string { return NewMessage(field, InvalidRFC1123HostnameMessage) } // NewMessage returns a new detail string combining the provided field and // message func NewMessage(field, message string) string { return strings.Join([]string{field, message}, " ") }