Problem
Two core processors wrap large blocks in bare except Exception (both do call logger.exception, so tracebacks are logged — but the granularity hides real failures):
packages/text-to-code/.../eicr_processor.py:47-76 — the try wraps the entire nested node/sub-xpath loop. A single malformed sub-node aborts extraction for the whole (base_xpath, data_field) and returns whatever was collected so far. Early returns here could be masking systematic extraction failures.
packages/text-to-code/.../schematron_processor.py:74-123 — per-validationResult try/except … continue. Line 92 (assertion_id_elem.text.strip()) assumes assertionID exists; when it doesn't, the resulting AttributeError is swallowed and the error is silently dropped.
Proposed scope
- Narrow the
try in get_text_candidates to per-sub-node so one bad node doesn't kill the batch; catch specific exceptions (etree.XPathError, AttributeError, ValueError).
- In
schematron_processor, guard assertion_id_elem is None explicitly (like the other *_elem None checks at :83-89) instead of relying on the broad except; narrow the catch.
- Add a metric/structured-log counter distinguishing "no candidates (expected)" from "extraction raised" so the passthrough investigation has signal.
Acceptance criteria
- Tests cover: malformed sub-node mid-loop (other candidates still returned); a
validationResult missing assertionID (handled deterministically, logged, not crashed).
- No bare
except Exception remains in these two functions.
Problem
Two core processors wrap large blocks in bare
except Exception(both do calllogger.exception, so tracebacks are logged — but the granularity hides real failures):packages/text-to-code/.../eicr_processor.py:47-76— thetrywraps the entire nested node/sub-xpath loop. A single malformed sub-node aborts extraction for the whole(base_xpath, data_field)and returns whatever was collected so far. Early returns here could be masking systematic extraction failures.packages/text-to-code/.../schematron_processor.py:74-123— per-validationResulttry/except … continue. Line 92 (assertion_id_elem.text.strip()) assumesassertionIDexists; when it doesn't, the resultingAttributeErroris swallowed and the error is silently dropped.Proposed scope
tryinget_text_candidatesto per-sub-node so one bad node doesn't kill the batch; catch specific exceptions (etree.XPathError,AttributeError,ValueError).schematron_processor, guardassertion_id_elem is Noneexplicitly (like the other*_elemNone checks at:83-89) instead of relying on the broad except; narrow the catch.Acceptance criteria
validationResultmissingassertionID(handled deterministically, logged, not crashed).except Exceptionremains in these two functions.