The CUE Go API contains several functions that might need to communicate
runtime errors to their caller, such as problems during evaluation or
validation. They do this using the
cue/errors.Error
type,
and the cue/errors
package contains functions that allow you to interrogate and manipulate these
errors.
This guide demonstrates how to catch these errors
and how to use the cue/errors
package to examine their details.
Set up some CUE code
If you don’t already have an existing CUE module, initialize one to contain a configuration:
$ cue mod init cue.example
If you don’t already have some known-bad CUE that contains evaluation or validation errors, create some:
package example
#Schema: {
i: int
s: string
}
val: #Schema & {
i: "hello" // Not an int.
s: 42 // Not a string.
}
Verify that the configuration does not validate successfully, as expected:
$ cue vet
val.i: conflicting values int and "hello" (mismatched types int and string):
./bad.cue:4:5
./bad.cue:9:5
val.s: conflicting values string and 42 (mismatched types string and int):
./bad.cue:5:5
./bad.cue:10:5
Set up a Go program
If you don’t already have an existing Go module, initialize one to contain a Go program:
$ go mod init go.example
...
Write a Go program that loads the CUE, evalutes some of it, and then prints a summary and details of any evaluation or validation errors that ocurr:
package main
import (
"fmt"
"cuelang.org/go/cue"
"cuelang.org/go/cue/cuecontext"
"cuelang.org/go/cue/errors"
"cuelang.org/go/cue/load"
)
func main() {
ctx := cuecontext.New()
// Load the CUE package in the current directory and extract a value from it.
insts := load.Instances([]string{"."}, nil)
pkg := ctx.BuildInstance(insts[0])
val := pkg.LookupPath(cue.ParsePath("val"))
// Check if the value evaluates successfully.
err := val.Validate(cue.Concrete(true))
if err != nil {
// Extract one or more errors from the evaluation.
errs := errors.Errors(err)
// Display information about the errors.
fmt.Println(`# Error summary [err]:`)
fmt.Printf("%v\n\n", err)
fmt.Println(`# Error details [errors.Details(err)]:`)
fmt.Printf("%v\n", errors.Details(err, nil))
fmt.Println(`# Error count [len(errs)]:`)
fmt.Printf("%d\n", len(errs))
}
}
Add a dependency on cuelang.org/go
and ensure the Go module is tidy:
$ go get cuelang.org/go@v0.12.0-alpha.1.0.20241220130530-e4c4b8e8a15f
...
$ go mod tidy
...
You can use @latest
in place of the specific version mentioned here.
Run the Go program
Run the Go program:
$ go run .
# Error summary [err]:
val.i: conflicting values int and "hello" (mismatched types int and string) (and 1 more errors)
# Error details [errors.Details(err)]:
val.i: conflicting values int and "hello" (mismatched types int and string):
/home/runner/bad.cue:4:5
/home/runner/bad.cue:9:5
val.s: conflicting values string and 42 (mismatched types string and int):
/home/runner/bad.cue:5:5
/home/runner/bad.cue:10:5
# Error count [len(errs)]:
2
Notice that
cue/errors.Details
is
simply a convenience function that returns the error texts of the underlying
errors, aggregated as a single string. The information and metadata contained
in each underlying error can be accessed by iterating through the slice of
individual errors returned by the
cue/errors.Errors
method.
Related content
- Tag: go api – pages documenting and using the Go API
- Go API:
cue/errors
– package documentation