v3.22.7: a raised card error honours the step's on_fail

The runner's step loop caught an exception and hard-coded status "error" +
stop, ignoring on_fail - so a file-read of an absent optional file
(re-verified live on 3.22.6: MF/A153/49AC, note "6a82: Wrong parameters -
File not found", on_fail "warning" still stopped the run) could not express
the "read an optional file" pattern (49AC is documented optional: its
absence means no menu password).

The handler now treats a raised error as a failed "Error" check at the
step's level (the message as actual/detail and the note): on_fail "warning"
warns and the run continues, the default still stops; the drain-if-pending
behaviour is unchanged.  Every raised exception is treated the same - the
two "file absent" raise paths (pySim's SwMatchError for model files and
probe_file's RuntimeError with the decoded SW for custom FIDs) cannot be
told apart by type, and load-time validation (normalise_script) stays
strict.

Docs: the guide's on_fail paragraph and run-errors list (the 6A82 bullet),
api.md and help EN/RU.  Tests: a raising file-read with on_fail "warning"
warns and the next step runs; without on_fail the run still stops.
843 frontend + 821 Python; sw cache simple-v411.
This commit is contained in:
2026-10-07 00:53:20 +03:00
parent 0fa1dee4b5
commit 00675ca09c
9 changed files with 76 additions and 14 deletions
+3 -1
View File
@@ -753,7 +753,9 @@ step left pending (`91XX`).
the decoded PoR of this exchange (inline or SEND SHORT MESSAGE; at least one
field). `on_fail` is `error` (terminates the script) or `warning` (continues)
and applies to every step failure - including an expectation that finds no
pending command (v3.21.0; `warning` is the tolerant consume-if-pending form).
pending command (v3.21.0; `warning` is the tolerant consume-if-pending form)
and a card/transport error raised during the step (v3.22.7 - the error is
reported as a failed `Error` check at the step's level).
**Expectation steps** (`type: "expect"`) require a command pending from the
previous step (`91XX`); they never poll - a `9000` response means no command
+9 -2
View File
@@ -229,8 +229,11 @@ TEST-RUN step 4: MENU-SELECT ENVELOPE=80c2000009d30702020181900101 item=1 ('One'
Every step may carry `on_fail`: `"error"` (default - stops the run) or
`"warning"` (continues, the report shows ⚠). Each entry of `checks` may
override it with its own `on_fail`. The level applies to **every** step
failure, including an expectation that finds no pending command (v3.21.0) -
the tolerant "consume a command if there is one" form is an expectation with
failure, including an expectation that finds no pending command (v3.21.0)
and a **card error raised during the step** (v3.22.7 - an absent optional
file's `6A82`, a refused SELECT: with `on_fail: "warning"` the step warns,
the report shows the error as a failed check, and the run continues) - the
tolerant "consume a command if there is one" form is an expectation with
`on_fail: "warning"`; to drain and confirm the card is idle, use the
`proactive-drain` action.
@@ -649,6 +652,10 @@ PoR-in-submit (with the transport asserted by the expectation):
names it). A `status` action with `attempts > 1` polls until a command
appears when the card delivers on poll; `on_fail: "warning"` tolerates the
empty case, and the `proactive-drain` action drains and confirms idle.
- `6A82: … File not found` (or another raised card error) - the step's
`on_fail` decides: the default stops the run, `on_fail: "warning"` warns
and continues - the pattern for an **optional** file (`49AC` is documented
optional: its absence means no menu password).
- `menu-select: no menu item matches …` - the error lists the cached menu; a
miss on an explicit `case_sensitive: true` names the case-insensitive
candidates.