cue: generate error node rather than panic on faulty output.
Issue #593
Change-Id: Icf1690e0ea631ee650a5b3962e7777608a0229c6
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/7722
Reviewed-by: CUE cueckoo <cueckoo@gmail.com>
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
diff --git a/cue/format/format_test.go b/cue/format/format_test.go
index b0da92e..47a0b6a 100644
--- a/cue/format/format_test.go
+++ b/cue/format/format_test.go
@@ -286,7 +286,7 @@
// Verify that the printer doesn't crash if the AST contains BadXXX nodes.
func TestBadNodes(t *testing.T) {
const src = "package p\n("
- const res = "package p\n\n(BadExpr)\n"
+ const res = "package p\n\n(_|_)\n"
f, err := parser.ParseFile("", src, parser.ParseComments)
if err == nil {
t.Error("expected illegal program") // error in test
diff --git a/cue/format/node.go b/cue/format/node.go
index ebbb64f..8e9192f 100644
--- a/cue/format/node.go
+++ b/cue/format/node.go
@@ -532,7 +532,7 @@
switch x := expr.(type) {
case *ast.BadExpr:
- f.print(x.From, "BadExpr")
+ f.print(x.From, "_|_")
case *ast.BottomLit:
f.print(x.Bottom, token.BOTTOM)
diff --git a/cue/types.go b/cue/types.go
index fdb2643..d9aa414 100644
--- a/cue/types.go
+++ b/cue/types.go
@@ -939,6 +939,29 @@
pkgID := v.instance().ID()
+ bad := func(name string, err error) ast.Node {
+ const format = `"%s: internal error
+Error: %s
+
+Profile:
+%#v
+
+Value:
+%v
+
+You could file a bug with the above information at:
+ https://github.com/cuelang/cue/issues/new?assignees=&labels=NeedsInvestigation&template=bug_report.md&title=.
+`
+ cg := &ast.CommentGroup{Doc: true}
+ msg := fmt.Sprintf(format, name, err, p, v)
+ for _, line := range strings.Split(msg, "\n") {
+ cg.List = append(cg.List, &ast.Comment{Text: "// " + line})
+ }
+ x := &ast.BadExpr{}
+ ast.AddComment(x, cg)
+ return x
+ }
+
// var expr ast.Expr
var err error
var f *ast.File
@@ -947,19 +970,19 @@
var expr ast.Expr
expr, err = p.Value(v.idx.Runtime, pkgID, v.v)
if err != nil {
- return nil
+ return bad(`"cuelang.org/go/internal/core/export".Value`, err)
}
// This introduces gratuitous unshadowing!
f, err = astutil.ToFile(expr)
if err != nil {
- return nil
+ return bad(`"cuelang.org/go/ast/astutil".ToFile`, err)
}
// return expr
} else {
f, err = p.Def(v.idx.Runtime, pkgID, v.v)
if err != nil {
- panic(err)
+ return bad(`"cuelang.org/go/internal/core/export".Def`, err)
}
}