cat / 012
clone

a spreadsheet for the terminal: lotus 1-2-3 looks, google sheets keys and formulas, one go binary

Update typesafe-go to v0.2.0 and check the service's limits early

Dami committed e31e05c
v0.2.0 validates requests against the hosted API's limits before any
network call. The JEV functions now check the same limits themselves (at
most 255 labels and 10 score levels, a non-empty question), so an
oversized question shows #VALUE! at once instead of Loading… followed by
a failure. A test keeps the engine's limits equal to the SDK's.
commit
e31e05c4c678d894e728340d937c982bca4692c8
parent
33ba94ae00bfe2baa213073eefdc6760e704a938
author
Dami <dami.etoile@gmail.com>
4 files changed, +57 -7
Mgo.mod2+-
Mgo.sum2++
Minternal/jev/jev_test.go31++++++++++++++++++++++++++++++
Minternal/sheet/functions_jev.go29++++++++++++++++++++++------
M go.mod +1 -1
M go.sum +2 -0
M internal/jev/jev_test.go +31 -0
M internal/sheet/functions_jev.go +23 -6
@@ -33,6 +33,14 @@ func init() {
3333 )3434 }3535 36+// Limits the JEV service enforces (typesafe.MaxChoiceOptions and37+// MaxScoreLevels; internal/jev tests keep them in step). Checking them here38+// shows #VALUE! at once instead of a request that is bound to fail.39+const (40+ maxChoiceLabels = 25541+ maxScoreLevels = 1042+)43+3644 // ErrRemote is a question the model couldn't answer, e.g. a network3745 // failure; the context line says why.3846 var ErrRemote = Value{Kind: Error, Str: "#ERROR!"}
@@ -112,6 +120,15 @@ func jevText(n Node, get lookup) (string, error) {
112120 return strings.TrimSpace(text(v)), nil113121 }114122 123+// jevQuestion reads the question, which must not be empty.124+func jevQuestion(n Node, get lookup) (string, error) {125+ q, err := jevText(n, get)126+ if err == nil && q == "" {127+ err = inputError{ErrValue}128+ }129+ return q, err130+}131+115132 // jevList reads a list argument: a range of cells, or one text of116133 // comma-separated items like "positive, negative, neutral". Blanks are117134 // skipped.
@@ -150,7 +167,7 @@ func yesNoCall(args []Node, get lookup) (RemoteCall, error) {
150167 if err != nil {151168 return RemoteCall{}, err152169 }153- q, err := jevText(args[1], get)170+ q, err := jevQuestion(args[1], get)154171 if err != nil {155172 return RemoteCall{}, err156173 }
@@ -170,7 +187,7 @@ func choiceCall(args []Node, get lookup) (RemoteCall, error) {
170187 if err != nil {171188 return RemoteCall{}, err172189 }173- q, err := jevText(args[1], get)190+ q, err := jevQuestion(args[1], get)174191 if err != nil {175192 return RemoteCall{}, err176193 }
@@ -184,8 +201,8 @@ func choiceCall(args []Node, get lookup) (RemoteCall, error) {
184201 return RemoteCall{}, err185202 }186203 }187- if len(labels) < 2 {188- return RemoteCall{}, inputError{ErrValue} // nothing to choose between204+ if len(labels) < 2 || len(labels) > maxChoiceLabels {205+ return RemoteCall{}, inputError{ErrValue} // nothing to choose between, or too many189206 }190207 criteria := make(map[string]string, len(labels))191208 for i, l := range labels {
@@ -202,7 +219,7 @@ func scoreCall(args []Node, get lookup) (RemoteCall, error) {
202219 if err != nil {203220 return RemoteCall{}, err204221 }205- q, err := jevText(args[1], get)222+ q, err := jevQuestion(args[1], get)206223 if err != nil {207224 return RemoteCall{}, err208225 }
@@ -210,7 +227,7 @@ func scoreCall(args []Node, get lookup) (RemoteCall, error) {
210227 if err != nil {211228 return RemoteCall{}, err212229 }213- if len(levels) < 2 {230+ if len(levels) < 2 || len(levels) > maxScoreLevels {214231 return RemoteCall{}, inputError{ErrValue}215232 }216233 return RemoteCall{Kind: "score", State: state, Instructions: q, Criteria: levels}, nil