General
My checker blamed the other tool, and the defect was in the one doing the blaming
Mahiro Hirakawa DEV Community 周榜
2 views
A verifier went red and named a neighbouring tool as the cause. Three of eight rows could not be matched, and the reason code said the rows had the wrong shape.
Two things were wrong with that. The neighbouring tool was innocent, and the reason code was lying.
FAIL rows=3/8 unmatched reason=BAD_SHAPE
First, the accusation was never measured
The report blamed the other tool's records. Checking it took one question: does the accused component ever read the file in question?
It does not. No row in its table names that path, and the reader never opens it. Measured, not assumed.
That is worth doing before anything else, because a blame string in a failure message is written by whoever wrote the failure message. It is a hypothesis that got printed in the position where a finding goes.
The real cause was in the accuser, and it broke the accuser's own rule
The verifier anchors each row to a block of code by a key. Its own specification says, in one line: anchor by key, not by line number.
Its keys looked like this:
map.mjs::function lineSha@2490
That trailing @2490 is a line number. An edit elsewhere in the file moved the block to 2515, the key stopped matching, and three rows found nothing.
So the tool that shipped "do not anchor by line" was anchoring by line, inside the key it used to prove it was not.
The reason code was the second defect
BAD_SHAPE says the row is malformed. The truth was that the row was fine and its anchor had moved. Those are different repairs: one edits the row, the other edits the anchoring scheme. A reader trusting the reason code would have rewritten three perfectly good rows.
what the code said
what was true
what it would have led you to do
the row has the wrong shape
the row is correct
rewrite the row
(nothing)
the key embeds a line number
strip the line number from the key
A failure mode that names the wrong failure is worse than a generic one. FAILED tells you to go look. BAD_SHAPE tells you where to look, confidently, in the wrong place.
The fix that I want to keep is the one about vocabulary
Two changes went in. The key now strips the trailing @<digits>. And the matcher now demands exactly one block per declared row.
That second one needed an error for "found zero, or found several". There was already a word for a stale anchor, and the temptation was to mint a precise new one.
We reused the existing word.
before: reasons = {STALE, BAD_SHAPE, ...} n=12
after: reasons = {STALE, BAD_SHAPE, ...} n=12
The reason is boring and it is the point: every run's totals are reported against the set of reason codes. Add a code and every historical count silently means something slightly different, and the before-and-after that would have proved the fix worked is no longer a comparison. A new word costs a denominator. Reusing an accurate-enough one costs nothing.
New vocabulary is a schema change wearing the clothes of a log message.
One more thing that fell out
The rebuild and the re-anchor steps are not commutative. Run the rebuild first and it reads a row that the re-anchor has not corrected yet, and reports a mismatch that is an artifact of the order.
Nothing in either tool said so. It is the kind of constraint that lives only in whoever ran it last, until someone writes it down, so: it is written down now, as a row in the workflow rather than a comment in a script.
What I took from it
Check who is being accused before fixing anything. One grep settled it here, and without it the next hour goes into the wrong module.
A tool that documents a rule is not a tool that follows it. The invariant was in the spec, in one sentence, and the violation was in the format string three files away. Nothing connected them, so nothing caught it.
Your own instrument is a candidate, and usually the looser one. Between two components that disagree, the one with the fuzzier contract is where I should look first, and the one I wrote most recently is usually that one.
Read original: https://dev.to/mahirhir/my-checker-blamed-the-other-tool-and-the-defect-was-in-the-one-doing-the-blaming-3cpo
← Previous
StarCraft returns in 2030 as an open-world shooter
Next →
The .NET HTTP Failure Nobody Sees Coming -Najeeb Ullah
Related
I Finally Built My Developer Portfolio
General
2
Dev.to (EN Zone)
I added three new checks and ten unrelated tests went red. That was the system working.
General
4
DEV Community
Full Disk Access Was On, and macOS Still Refused the App
General
4
DEV Community 周榜
A Screenshot Is Not an Agent Failure Artifact
General
4
DEV Community 周榜
Comments0
No comments yet — be the first