Skip to content

Commit

Permalink
thema: Add and use new translation sentinel errors
Browse files Browse the repository at this point in the history
  • Loading branch information
sam boyer committed Jun 28, 2023
1 parent ce1c611 commit bff274a
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 9 deletions.
21 changes: 21 additions & 0 deletions errors/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,27 @@ var (
ErrInvalidOutOfBounds = errors.New("data is out of schema bounds")
)

// Translation errors. These all occur as a result of an invalid lens. Currently
// these may be returned from [thema.Instance.TranslateErr]. Eventually, it is
// hoped that they will be caught statically in [thema.BindLineage] and cannot
// occur at runtime.
var (
// ErrInvalidLens indicates that a lens is not correctly written. It is the parent
// to all other lens and translation errors, and is a child of ErrInvalidLineage.
ErrInvalidLens = errors.New("lens is invalid")

// ErrLensIncomplete indicates that translating some valid data through
// a lens produced a non-concrete result. This always indicates a problem with the
// lens as it is written, and as such is a child of ErrInvalidLens.
ErrLensIncomplete = errors.New("result of lens translation is not concrete")

// ErrLensResultIsInvalidData indicates that translating some valid data through a
// lens produced a result that was not an instance of the target schema. This
// always indicates a problem with the lens as it is written, and as such is a
// child of ErrInvalidLens.
ErrLensResultIsInvalidData = errors.New("result of lens translation is not valid for target schema")
)

// Lower level general errors
var (
// ErrValueNotExist indicates that a necessary CUE value did not exist.
Expand Down
27 changes: 18 additions & 9 deletions instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ import (
"fmt"

"cuelang.org/go/cue"
"cuelang.org/go/cue/errors"
cerrors "cuelang.org/go/cue/errors"
"cuelang.org/go/pkg/encoding/json"
"github.com/cockroachdb/errors"
terrors "github.com/grafana/thema/errors"
)

// BindInstanceType produces a TypedInstance, given an Instance and a
Expand Down Expand Up @@ -227,22 +230,28 @@ func (i *Instance) TranslateErr(to SyntacticVersion) (*Instance, TranslationLacu
}

if out.Err() != nil {
panic(errors.Details(out.Err(), nil))
return nil, nil, errors.Mark(out.Err(), terrors.ErrInvalidLens)
}

lac := make(multiTranslationLacunas, 0)
out.LookupPath(cue.MakePath(cue.Str("lacunas"))).Decode(&lac)

// Attempt to evaluate #Translate result into a concrete cue.Value, if possible.
// Attempt to evaluate #Translate result to remove intermediate structures created by #Translate.
// Otherwise, all the #Translate results are non-concrete, which leads to undesired effects.
raw, _ := out.LookupPath(cue.MakePath(cue.Str("result"), cue.Str("result"))).Default()

return &Instance{
valid: true,
raw: raw,
name: i.name,
sch: newsch,
}, lac
// Check that the result is concrete by trying to marshal/export it as JSON
_, err = json.Marshal(raw)
if err != nil {
return nil, nil, errors.Mark(fmt.Errorf("lens produced a non-concrete result: %s", cerrors.Details(err, nil)), terrors.ErrLensIncomplete)
}

// Ensure the result is a valid instance of the target schema
inst, err := newsch.Validate(raw)
if err != nil {
return nil, nil, errors.Mark(err, terrors.ErrLensResultIsInvalidData)
}
return inst, lac, err
}

type multiTranslationLacunas []struct {
Expand Down

0 comments on commit bff274a

Please sign in to comment.