entc/gen: introduce validation errors (#547)

This introduces the concept of validation errors, where we have a high
level validation error which wraps a more detailed error message.

The higher level `ValidationError` is set up in the generated files, much
like the `NotFoundError` and `ConstraintError` and is accompanied by an
`IsValidationError` check method. Thus, it can be used as follows:

```go
t, err := tx.Team.Create().SetName(input.Name).Save(ctx)
if ent.IsValidationError(err) {
        // handle validation error response
}
```
This commit is contained in:
Jelmer Snoeck
2020-06-17 11:11:39 -03:00
committed by GitHub
parent c616f7f2e7
commit b150cde478
143 changed files with 846 additions and 246 deletions

View File

@@ -56,13 +56,13 @@ func (cc *CardCreate) Mutation() *CardMutation {
// Save creates the Card in the database.
func (cc *CardCreate) Save(ctx context.Context) (*Card, error) {
if _, ok := cc.mutation.Expired(); !ok {
return nil, errors.New("ent: missing required field \"expired\"")
return nil, &ValidationError{Name: "expired", err: errors.New("ent: missing required field \"expired\"")}
}
if _, ok := cc.mutation.Number(); !ok {
return nil, errors.New("ent: missing required field \"number\"")
return nil, &ValidationError{Name: "number", err: errors.New("ent: missing required field \"number\"")}
}
if _, ok := cc.mutation.OwnerID(); !ok {
return nil, errors.New("ent: missing required edge \"owner\"")
return nil, &ValidationError{Name: "owner", err: errors.New("ent: missing required edge \"owner\"")}
}
var (
err error

View File

@@ -310,7 +310,7 @@ func (cuo *CardUpdateOne) sqlSave(ctx context.Context) (c *Card, err error) {
}
id, ok := cuo.mutation.ID()
if !ok {
return nil, fmt.Errorf("missing Card.ID for update")
return nil, &ValidationError{Name: "ID", err: fmt.Errorf("missing Card.ID for update")}
}
_spec.Node.ID.Value = id
if value, ok := cuo.mutation.Expired(); ok {

View File

@@ -100,6 +100,31 @@ func Sum(field string) AggregateFunc {
}
}
// ValidationError returns when validating a field fails.
type ValidationError struct {
Name string // Field or edge name.
err error
}
// Error implements the error interface.
func (e *ValidationError) Error() string {
return e.err.Error()
}
// Unwrap implements the errors.Wrapper interface.
func (e *ValidationError) Unwrap() error {
return e.err
}
// IsValidationError returns a boolean indicating whether the error is a validaton error.
func IsValidationError(err error) bool {
if err == nil {
return false
}
var e *ValidationError
return errors.As(err, &e)
}
// NotFoundError returns when trying to fetch a specific entity and it was not found in the database.
type NotFoundError struct {
label string

View File

@@ -63,10 +63,10 @@ func (uc *UserCreate) Mutation() *UserMutation {
// Save creates the User in the database.
func (uc *UserCreate) Save(ctx context.Context) (*User, error) {
if _, ok := uc.mutation.Age(); !ok {
return nil, errors.New("ent: missing required field \"age\"")
return nil, &ValidationError{Name: "age", err: errors.New("ent: missing required field \"age\"")}
}
if _, ok := uc.mutation.Name(); !ok {
return nil, errors.New("ent: missing required field \"name\"")
return nil, &ValidationError{Name: "name", err: errors.New("ent: missing required field \"name\"")}
}
var (
err error

View File

@@ -339,7 +339,7 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) {
}
id, ok := uuo.mutation.ID()
if !ok {
return nil, fmt.Errorf("missing User.ID for update")
return nil, &ValidationError{Name: "ID", err: fmt.Errorf("missing User.ID for update")}
}
_spec.Node.ID.Value = id
if value, ok := uuo.mutation.Age(); ok {