Lead a refusal of a held module's stand-in with why the module was held, so its first reason is never hidden (issue 774)
mesh/delivery merged: source.main moved to novox/mesh-sdk@6a71d29b3331
mesh/delivery-group group fix/kept-read-and-foreseen-account merged: every member is merged
mesh/check pass 4e9621edd664 on 14de8dadb4ce | unit 2719 run, 602 kept, 36 skipped | integration 2731 run, 645 kept, 29 skipped | over bound: unit, in…
mesh/delivery merged: source.main moved to novox/mesh-sdk@6a71d29b3331
mesh/delivery-group group fix/kept-read-and-foreseen-account merged: every member is merged
mesh/check pass 4e9621edd664 on 14de8dadb4ce | unit 2719 run, 602 kept, 36 skipped | integration 2731 run, 645 kept, 29 skipped | over bound: unit, in…
The proposal on ace said only "mesh-self-check runs as its own account and declares no own secret broker": the words
of its bare stub, held for "has no bus credential", which no one saw. The second hidden first reason of the day, after
"0 bundle(s)".
Quick fix: log the held map in composeEach. Thorough fix: firstReason leads a refusal no culprit is found for with the
first reason of every held module it names ("<m> is held: <why>; its stand-in is then refused: <err>"), for Compose and
the node's Answer alike; the hold's own why already keeps its first words. Chose thorough.
This commit is contained in:
@@ -335,7 +335,7 @@ func composeEach(in compose.Input, node string, fps map[string]string, applied b
|
||||
if err != nil {
|
||||
module, leave := culprit(in, node, fps, mode, failed, err)
|
||||
if module == "" {
|
||||
return nil, nil, nil, err
|
||||
return nil, nil, nil, firstReason(err, failed)
|
||||
}
|
||||
hold(module, err.Error(), leave)
|
||||
continue
|
||||
@@ -373,6 +373,23 @@ func composeEach(in compose.Input, node string, fps map[string]string, applied b
|
||||
return out, skipped, stood, nil
|
||||
}
|
||||
|
||||
// firstReason is err, a refusal no culprit is found for, led by the first reason of each held module it names: a held
|
||||
// module's stand-in refused later never replaces why it was held (issue 774, 2026-10-30: mesh-self-check on ace held for
|
||||
// "has no bus credential", then refused as "runs as its own account and declares no own secret broker", its bare stub's
|
||||
// words, which were all the proposal's refusal said).
|
||||
func firstReason(err error, failed map[string]string) error {
|
||||
var named []string
|
||||
for _, m := range sortedKeys(failed) {
|
||||
if strings.Contains(err.Error(), m) {
|
||||
named = append(named, m+" is held: "+failed[m])
|
||||
}
|
||||
}
|
||||
if len(named) == 0 {
|
||||
return err
|
||||
}
|
||||
return fmt.Errorf("%s; its stand-in is then refused: %w", strings.Join(named, "; "), err)
|
||||
}
|
||||
|
||||
// blames says the composition with m's stub (again) makes m the culprit of err: it composes, or fails otherwise. The
|
||||
// runtime's stub is never a runtime (no build is taken in, so it carries no bundle) and always fails otherwise: it is
|
||||
// the culprit only where its stub composes (issue 774, 2026-10-30 19:30: node-tools held for any error naming it).
|
||||
|
||||
@@ -142,6 +142,7 @@ func TestInput(t *testing.T) {
|
||||
t.Run("a node refused whole says what it held", aNodeRefusedWholeSaysWhatItHeld)
|
||||
t.Run("the runtime is blamed only where its stub composes", theRuntimeIsBlamedOnlyWhereItsStubComposes)
|
||||
t.Run("a running module waits for its build", aRunningModuleWaitsForItsBuild)
|
||||
t.Run("a held module's first reason leads", aHeldModulesFirstReasonLeads)
|
||||
t.Run("another node not resolved is named", otherNodeNotResolvedIsNamed)
|
||||
ctx := context.Background()
|
||||
xterm, err := os.ReadFile("../../catalogue/testdata/catalogue-835bf22b-xterm.module.json")
|
||||
|
||||
@@ -131,3 +131,23 @@ func rawStrings(rs []json.RawMessage) []string {
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// Issue 774: a refusal of a held module's stand-in leads with why the module was held, its first reason, as mesh-self-check's
|
||||
// on ace should have; a refusal naming no held module is as it was.
|
||||
func aHeldModulesFirstReasonLeads(t *testing.T) {
|
||||
held := map[string]string{"mesh-self-check": "mesh-self-check on ace has no bus credential: nothing was issued for ace.mesh-self-check"}
|
||||
for _, row := range []struct {
|
||||
err, want string
|
||||
}{
|
||||
{"mesh-self-check runs as its own account and declares no own secret broker",
|
||||
"mesh-self-check is held: mesh-self-check on ace has no bus credential: nothing was issued for ace.mesh-self-check; " +
|
||||
"its stand-in is then refused: mesh-self-check runs as its own account and declares no own secret broker"},
|
||||
{"ace is the hub and has no endpoint", "ace is the hub and has no endpoint"},
|
||||
} {
|
||||
err := errors.New(row.err)
|
||||
got := firstReason(err, held)
|
||||
if got.Error() != row.want || !errors.Is(got, err) {
|
||||
t.Errorf("refused %q, want %q", got, row.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user