fangorn/ex_git_objectstore
public
ref:45d96677973ca2d8dfc339357d301f3705e6f7c3
feat: preserve error detail and fail loudly on bad filter specs
Three error-handling gaps surfaced in grading:
1. `sanitize_error` flattened `{tag, "detail"}` to just the tag, so
the git client saw `ng <ref> hook_rejected` with zero context.
Now preserves up to 80 chars of detail after the tag:
ng <ref> hook_rejected: CODEOWNERS approval required for main
2. Unparseable filter specs were logged and silently ignored. The
server then returned a FULL pack to a client that had asked for
a partial one — the client would set `remote.origin.promisor=true`
against a pack that contradicted the filter. Bad. Now the handler
returns a band-3 sideband error ("ERR filter spec not supported:
<spec>") + flush, and the git client surfaces it as a fatal error.
3. `rollback_refs` ignored per-ref `Ref.put` / `Ref.delete` failures.
A failed rollback leaves ref state inconsistent with the
report-status reply the client just received. Now emits a
`Logger.error` + telemetry event so operators can alert on it.
Tests:
- `ng line surfaces the hook's reason detail, not just the tag` —
pushes through an update_hook returning
`{:error, {:hook_rejected, "CODEOWNERS approval required"}}`;
asserts the rejection message in `git push` output.
- `unparseable filter spec is rejected with ERR, not silently
ignored` — `git clone --filter=garbage:unknown-spec` must fail
with a protocol error, not a successful-looking full-pack clone.
SHA:
45d96677973ca2d8dfc339357d301f3705e6f7c3
Author:
Cole Christensen <cole.christensen@macmillan.com>
Date:
2026-04-19 01:06
Parents:
8701785
4 files changed
+170
-23
| Type | ||
|---|---|---|
|
|
lib/ex_git_objectstore/protocol/receive_pack.ex | +49 −7 |
|
||
|
|
lib/ex_git_objectstore/protocol/upload_pack_v2.ex | +46 −16 |
|
||