Add GraphQL fault-injection proxy (node + Python)#2
Open
jmbrunskill wants to merge 2 commits into
Open
Conversation
…on schema Mid-flight commit; see WIP.md in the directory for context on what's done, what's broken (slow_stream trickling), and next steps. - Split monorepo'd directory into node/ and python/ subdirs with a top-level README that compares the two. - Extracted control-UI HTML out of both server.js and fault_injection_proxy.py into sibling control.html files. - Python only: rewrote against a two-stage rule schema (active + composable delay_ms / response.kind), deleted dead helpers, fixed OPTIONS-preflight-to-/graphql bug, rewrote control.html to match. slow_stream chunked trickling is broken; everything else verified. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Real chunked trickling via mitmproxy's flow.response.stream was unreliable (HTTP 200, empty body, then a client timeout), so the slow_stream / slow-trickle mode is removed rather than shipped broken. It's deferred to a future dev; python/README.md documents what an implementation needs to check (the Response.stream callable signature). - python: drop slow_stream from fault_injection_proxy.py + control.html (a fixed delay is still available via delay_ms / the Slow preset) - python: rewrite README for the two-stage rule schema; it was stale and still documented the old mode-based schema - scrub inaccurate "slow trickle" mentions from the top-level and node docs (the Node version never had it) and add a Future work section - record the outstanding code-review items and follow-up in WIP.md Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This was referenced Jun 15, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A reverse proxy for manual testing of typed GraphQL errors and the
connection-lost banner — companion to open-msupply
PR #11444.
It sits between the client and the real omSupply server, proxies normally,
and lets you swap individual operations for typed GraphQL errors
(
Unauthenticated,Forbidden,Bad user input,Internal error) orsimulate transport failures (offline, HTTP 500 no body, truncated body) via
a small web UI (
/__mock) and aPOST /__mock/controlJSON API.Two interchangeable implementations:
node/— zero-dependency Node 18+ proxy (the default pick).python/— mitmproxy reverse proxy, using a newer two-stage ruleschema (
activemaster switch + composabledelay_ms/response.kind).Most recent change (this pass)
slow_stream/ slow-trickle mode (code, UI, docs).Real chunked trickling via mitmproxy's
flow.response.streamwasunreliable — HTTP 200, empty body, then a client timeout — so it's removed
rather than shipped broken. A fixed delay is still available via
delay_ms/ the
Slowpreset.python/README.mdfor the two-stage schema (it was stale andstill documented the old
mode-based schema).Node docs (the Node version never had it) and added a Future work
section.
All tracked in
graphql-error-injection-proxy/WIP.md. The Node versionis still on the original
mode-based schema and was not touched beyond docaccuracy:
Slowpreset is a no-op bug —mode:passthrough + delay_ms:5000, butruleAppliesToreturns false for passthrough so the delay never fires(same root cause the Python rewrite fixed).
handleGraphqlshould bededuped.
catchin truncate mode silently destroys the socket — add aconsole.error.respondHttpStatuswrites a 26-byte body despite its "no body" comment.errorTypefor non-error modes is still TODO.Python (minor): verify the error body omits
extensionswhendetailis empty (Node omits the key; looks handled in the rewrite — worth a glance).
🔭 Follow-up work
implementations match again (this also fixes the Node
Slow-preset no-op).Response.streamcallable signature confirmed (single-chunkfn(bytes) -> bytesvs iteratorfn(chunks) -> Iterator[bytes]); seepython/README.md.rule shape into one place, or accept the divergence in writing.
Test steps
Manual-test helpers (no automated tests). Smoke-tested:
Python
brew install mitmproxy:8001, thenmitmdump -s ./fault_injection_proxy.py --mode reverse:http://localhost:8001 --listen-port 8000Off→ transparent passthrough;Forbidden→ typed error;delay_ms=2000 + kind=errortakes ~2s then errors;Fail next 3firesthen auto-deactivates. (Confirmed passing.)
slow_streampreset/option remains in the UI.Node:
node server.js(forwards:8000→:8001), open/__mock,exercise presets.
Notes for reviewers
shares the data-plane port. Localhost-only.
Labelled
enhancement.