mirror of https://github.com/docker/cli.git
127 lines
3.0 KiB
Go
127 lines
3.0 KiB
Go
|
package validation
|
||
|
|
||
|
import (
|
||
|
"encoding/json"
|
||
|
"fmt"
|
||
|
)
|
||
|
|
||
|
// VALIDATION ERRORS
|
||
|
|
||
|
// ErrValidation represents a general validation error
|
||
|
type ErrValidation struct {
|
||
|
Msg string
|
||
|
}
|
||
|
|
||
|
func (err ErrValidation) Error() string {
|
||
|
return fmt.Sprintf("An error occurred during validation: %s", err.Msg)
|
||
|
}
|
||
|
|
||
|
// ErrBadHierarchy represents missing metadata. Currently: a missing snapshot
|
||
|
// at this current time. When delegations are implemented it will also
|
||
|
// represent a missing delegation parent
|
||
|
type ErrBadHierarchy struct {
|
||
|
Missing string
|
||
|
Msg string
|
||
|
}
|
||
|
|
||
|
func (err ErrBadHierarchy) Error() string {
|
||
|
return fmt.Sprintf("Metadata hierarchy is incomplete: %s", err.Msg)
|
||
|
}
|
||
|
|
||
|
// ErrBadRoot represents a failure validating the root
|
||
|
type ErrBadRoot struct {
|
||
|
Msg string
|
||
|
}
|
||
|
|
||
|
func (err ErrBadRoot) Error() string {
|
||
|
return fmt.Sprintf("The root metadata is invalid: %s", err.Msg)
|
||
|
}
|
||
|
|
||
|
// ErrBadTargets represents a failure to validate a targets (incl delegations)
|
||
|
type ErrBadTargets struct {
|
||
|
Msg string
|
||
|
}
|
||
|
|
||
|
func (err ErrBadTargets) Error() string {
|
||
|
return fmt.Sprintf("The targets metadata is invalid: %s", err.Msg)
|
||
|
}
|
||
|
|
||
|
// ErrBadSnapshot represents a failure to validate the snapshot
|
||
|
type ErrBadSnapshot struct {
|
||
|
Msg string
|
||
|
}
|
||
|
|
||
|
func (err ErrBadSnapshot) Error() string {
|
||
|
return fmt.Sprintf("The snapshot metadata is invalid: %s", err.Msg)
|
||
|
}
|
||
|
|
||
|
// END VALIDATION ERRORS
|
||
|
|
||
|
// SerializableError is a struct that can be used to serialize an error as JSON
|
||
|
type SerializableError struct {
|
||
|
Name string
|
||
|
Error error
|
||
|
}
|
||
|
|
||
|
// UnmarshalJSON attempts to unmarshal the error into the right type
|
||
|
func (s *SerializableError) UnmarshalJSON(text []byte) (err error) {
|
||
|
var x struct{ Name string }
|
||
|
err = json.Unmarshal(text, &x)
|
||
|
if err != nil {
|
||
|
return
|
||
|
}
|
||
|
var theError error
|
||
|
switch x.Name {
|
||
|
case "ErrValidation":
|
||
|
var e struct{ Error ErrValidation }
|
||
|
err = json.Unmarshal(text, &e)
|
||
|
theError = e.Error
|
||
|
case "ErrBadHierarchy":
|
||
|
var e struct{ Error ErrBadHierarchy }
|
||
|
err = json.Unmarshal(text, &e)
|
||
|
theError = e.Error
|
||
|
case "ErrBadRoot":
|
||
|
var e struct{ Error ErrBadRoot }
|
||
|
err = json.Unmarshal(text, &e)
|
||
|
theError = e.Error
|
||
|
case "ErrBadTargets":
|
||
|
var e struct{ Error ErrBadTargets }
|
||
|
err = json.Unmarshal(text, &e)
|
||
|
theError = e.Error
|
||
|
case "ErrBadSnapshot":
|
||
|
var e struct{ Error ErrBadSnapshot }
|
||
|
err = json.Unmarshal(text, &e)
|
||
|
theError = e.Error
|
||
|
default:
|
||
|
err = fmt.Errorf("do not know how to unmarshal %s", x.Name)
|
||
|
return
|
||
|
}
|
||
|
if err != nil {
|
||
|
return
|
||
|
}
|
||
|
s.Name = x.Name
|
||
|
s.Error = theError
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
// NewSerializableError serializes one of the above errors into JSON
|
||
|
func NewSerializableError(err error) (*SerializableError, error) {
|
||
|
// make sure it's one of our errors
|
||
|
var name string
|
||
|
switch err.(type) {
|
||
|
case ErrValidation:
|
||
|
name = "ErrValidation"
|
||
|
case ErrBadHierarchy:
|
||
|
name = "ErrBadHierarchy"
|
||
|
case ErrBadRoot:
|
||
|
name = "ErrBadRoot"
|
||
|
case ErrBadTargets:
|
||
|
name = "ErrBadTargets"
|
||
|
case ErrBadSnapshot:
|
||
|
name = "ErrBadSnapshot"
|
||
|
default:
|
||
|
return nil, fmt.Errorf("does not support serializing non-validation errors")
|
||
|
}
|
||
|
return &SerializableError{Name: name, Error: err}, nil
|
||
|
}
|