Skip to content

Make Error processor failure injection explicit and deterministic #81

Description

@MasterOfBinary

Current outcome

Make the test utility inject the failures its callers request, so error-path tests cannot pass vacuously or use silently quantized rates.

Replanned on 2026-09-06 against GoBatch master 63ef757 and ShitQuant's recorder, enrichment, paper/replay, and flow workloads. This is an implementation target, not a claim that the behavior already exists.

Required behavior

  • Document zero FailFraction as no injected failures and require an explicit all-fail setting, or adopt another explicit representation with a complete migration; do not infer unset from a legitimate zero.
  • Replace reciprocal truncation with a declared deterministic fraction/count rule whose rounding and per-call/reset behavior are testable.
  • Specify invalid/out-of-range fraction behavior, including non-finite values if the field remains floating point.
  • Ensure representative callers that expect failure actually assert injected failures.
  • Keep this a small utility correction; no dependency on the deferred factory framework.

Verification and completion

Test zero, all-fail, 0.4 and 0.6, boundaries/invalid values and the documented deterministic sequence. Verify error-path fixtures fail when injection is disabled.

Follow the repository's formatting, race-test, vet/lint, package documentation, example and changelog requirements for the changed surface. Report the actual supported behavior and migration; do not treat a passing coverage percentage as proof of these outcomes.

Scope and relationships

Useful to reliable lifecycle/error tests; independent of Redis or broad API ergonomics. Preserve intended upstream item errors under the agreed contract.

Design history

The earlier report/prototype remains below for provenance; the requirements above supersede conflicting prescriptions. Existing discussion is preserved.

Original issue: processor.Error: zero value is a silent no-op (docs claim FailFraction defaults to 1.0), and quantization makes any fraction in (0.5,1.0) fail 100%

Two defects in processor/error.go (validated on master @ 58cee73; found in a deep review):

1. Zero value contradicts the documented default. The FailFraction doc says "1.0 means all items will have errors (default)" and the type doc says it "marks all incoming items with the given error" — but Process treats failFraction <= 0 as pass-through (error.go:39-42). So the obvious construction &processor.Error[int]{Err: myErr} errors nothing, and tests that use it to verify error handling pass vacuously. The package's own test betrays this: it sets FailFraction: 1.0, // Default - apply to all manually.

2. Integer quantization. failEvery := int(1.0 / failFraction) (error.go:51) truncates: 0.6 → failEvery=1 → 100% of items fail; 0.4 → 2 → exactly 50%. Only rates of the form 1/n are achievable, and the deterministic every-Nth pattern isn't "approximately half" as the doc implies.

Suggested fix: decide the semantics explicitly — either honor the documented all-fail default (requires distinguishing unset from 0.0, e.g. a constructor per #74's direction) or fix the docs to say zero = no failures; document or replace the 1/n quantization. This is a testing utility, so a breaking change is fine under the v0 policy.

Relations: surfaced while validating #74 (factories would not fix either defect); independent of PRs #65/#66.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions