Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitaly.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPavlo Strokov <pstrokov@gitlab.com>2023-02-15 01:28:39 +0300
committerPavlo Strokov <pstrokov@gitlab.com>2023-03-21 00:38:57 +0300
commite0b945da70367b68e9b1eb78386a1d2b6bfe9c95 (patch)
treed73132f0787daaaecf8bacc0046b889165228bf9 /internal/errors/cfgerror/validate.go
parent902f1f365fd2f0c8e190accdb092d533cc4692a9 (diff)
gitaly: Validation of Git configuration
We want to make errors of configuration validation more verbose and flexible to operate with. The idea is to produce a machine friendly output that is why the ValidationError structure is defined. The next steps are to refactor existing validation methods to return errors as instances of the ValidationError combined into ValidationErrors. The first refactored validation is for the Git type. It now has a new Validate method that returns all the validation errors found.
Diffstat (limited to 'internal/errors/cfgerror/validate.go')
-rw-r--r--internal/errors/cfgerror/validate.go98
1 files changed, 98 insertions, 0 deletions
diff --git a/internal/errors/cfgerror/validate.go b/internal/errors/cfgerror/validate.go
new file mode 100644
index 000000000..54a31123b
--- /dev/null
+++ b/internal/errors/cfgerror/validate.go
@@ -0,0 +1,98 @@
+package cfgerror
+
+import (
+ "errors"
+ "fmt"
+ "strings"
+)
+
+// ErrNotSet should be used when the value is not set, but it is required.
+var ErrNotSet = errors.New("not set")
+
+// ValidationError represents an issue with provided configuration.
+type ValidationError struct {
+ // Key represents a path to the field.
+ Key []string
+ // Cause contains a reason why validation failed.
+ Cause error
+}
+
+// Error to implement an error standard interface.
+// The string representation can have 3 different formats:
+// - when Key and Cause is set: "outer.inner: failure cause"
+// - when only Key is set: "outer.inner"
+// - when only Cause is set: "failure cause"
+func (ve ValidationError) Error() string {
+ if len(ve.Key) != 0 && ve.Cause != nil {
+ return fmt.Sprintf("%s: %v", strings.Join(ve.Key, "."), ve.Cause)
+ }
+ if len(ve.Key) != 0 {
+ return strings.Join(ve.Key, ".")
+ }
+ if ve.Cause != nil {
+ return fmt.Sprintf("%v", ve.Cause)
+ }
+ return ""
+}
+
+// NewValidationError creates a new ValidationError with provided parameters.
+func NewValidationError(err error, keys ...string) ValidationError {
+ return ValidationError{Key: keys, Cause: err}
+}
+
+// ValidationErrors is a list of ValidationError-s.
+type ValidationErrors []ValidationError
+
+// Append adds provided error into current list by enriching each ValidationError with the
+// provided keys or if provided err is not an instance of the ValidationError it will be wrapped
+// into it. In case the nil is provided nothing happens.
+func (vs ValidationErrors) Append(err error, keys ...string) ValidationErrors {
+ switch terr := err.(type) {
+ case nil:
+ return vs
+ case ValidationErrors:
+ for _, err := range terr {
+ vs = append(vs, ValidationError{
+ Key: append(keys, err.Key...),
+ Cause: err.Cause,
+ })
+ }
+ case ValidationError:
+ vs = append(vs, ValidationError{
+ Key: append(keys, terr.Key...),
+ Cause: terr.Cause,
+ })
+ default:
+ vs = append(vs, ValidationError{
+ Key: keys,
+ Cause: err,
+ })
+ }
+
+ return vs
+}
+
+// AsError returns nil if there are no elements and itself if there is at least one.
+func (vs ValidationErrors) AsError() error {
+ if len(vs) != 0 {
+ return vs
+ }
+ return nil
+}
+
+// Error transforms all validation errors into a single string joined by newline.
+func (vs ValidationErrors) Error() string {
+ var buf strings.Builder
+ for i, ve := range vs {
+ if i != 0 {
+ buf.WriteString("\n")
+ }
+ buf.WriteString(ve.Error())
+ }
+ return buf.String()
+}
+
+// New returns uninitialized ValidationErrors object.
+func New() ValidationErrors {
+ return nil
+}