Files
lefarcen 9cac9d6fc7 fix(collab): stop reporting cancelled team pulls as failures (#7405)
Revert the first-open download indicator and keep the one verified fix the
investigation produced.

The indicator is gone because it was measured, repeatedly, not to work. Against
a live vela Team workspace with two distinct accounts and two isolated daemons
it never rendered once — empty project or 3 MB one, warm data root or cold,
even racing the share. `proactiveContentPull` materializes the content before
the user can open it and wins that race every time, so the window the indicator
was built for does not exist. Its unit specs were green throughout, which is
exactly why they are not kept: they would have locked in coverage for a surface
nobody can reach.

What the investigation did find is that a deliberately cancelled `vela` child
was reported as a failure. `runVelaCommand` marks an abort with
`name: 'AbortError'` / `code: 'ABORT_ERR'` and keeps a separate `timeout`
termination, but nothing downstream read those markers. The proactive pull
scheduler aborts as ordinary control flow — `mergeIntentUpdate` when a higher
published version supersedes the fetch, `clearIntent` when an intent is
superseded or satisfied — so routine version churn logged
`authorized proactive team pull failed closed`, and sent at least one
investigation chasing a fault that never happened.

`isAbortedOperationError` now draws that line at both sinks: the `failed
closed` warning in collab-sync, and the single `onError` consumer that backs
proactive-content-pull's three raise sites (that module is deliberately
import-free, so the distinction belongs at its consumer).

Behaviour is unchanged; this is log correctness only. An aborted intent already
bumped `revision` and re-looped, or was removed outright, so it never reached
the retry/backoff accounting.

The predicate lives in a dependency-free module on purpose. Importing it from
`vela-command.ts` pulled `runtimes/env` + `runtimes/registry` into the route
module graph, where `collab-sync-routes.test.ts` mocks `integrations/vela.js`
with a single export — turning a passing pull into `register_failed`. That
regression was caught only by running the neighbouring suite.
2026-08-25 14:39:50 +00:00

64 lines
2.9 KiB
TypeScript

import { describe, expect, it } from 'vitest';
import { isAbortedOperationError } from '../src/integrations/aborted-error.js';
// A cancelled `vela` child is NOT a failure. The proactive team-pull scheduler
// aborts in-flight pulls on purpose in two places
// (`collab/proactive-content-pull.ts`):
//
// - `mergeIntentUpdate` aborts the current pull the moment a HIGHER version
// arrives, so the newer content is fetched instead of the stale one;
// - `clearIntent` aborts when the intent is superseded or already satisfied.
//
// `runVelaCommand` marks exactly this case with `name: 'AbortError'` and
// `code: 'ABORT_ERR'` (and keeps a separate `reason: 'timeout'` path for real
// deadline breaches). Nothing downstream ever read those markers, so every
// deliberate cancellation surfaced as `[od] authorized proactive team pull
// failed closed:` — observed live while investigating a first-open trace, where
// it sent the investigation after a phantom failure.
//
// This predicate is the seam the pull path uses to tell the two apart. It must
// never classify a real timeout or transport failure as a cancellation, or a
// genuine fault would be silently swallowed.
describe('isAbortedOperationError', () => {
it('recognizes a deliberately aborted vela command', () => {
const error = new Error('vela command aborted', {
cause: 'This operation was aborted',
});
error.name = 'AbortError';
Object.assign(error, { code: 'ABORT_ERR' });
expect(isAbortedOperationError(error)).toBe(true);
});
it('recognizes an abort identified only by its code', () => {
// DOMException-shaped aborts from other layers carry the code but may not
// preserve the name across a structured clone.
const error = Object.assign(new Error('aborted'), { code: 'ABORT_ERR' });
expect(isAbortedOperationError(error)).toBe(true);
});
it('does NOT treat a timeout as a cancellation', () => {
// `runVelaCommand`'s other termination reason. This is a real failure and
// must keep reaching the failure logging + retry accounting.
const error = new Error('vela command timed out after 30000ms');
error.name = 'TimeoutError';
expect(isAbortedOperationError(error)).toBe(false);
});
it('does NOT treat a transport failure as a cancellation', () => {
// The shape seen from the vela CLI itself when the API is unreachable.
const error = new Error(
'list team projects: context deadline exceeded (Client.Timeout exceeded while awaiting headers)',
);
expect(isAbortedOperationError(error)).toBe(false);
});
it('does NOT treat an arbitrary rejection as a cancellation', () => {
expect(isAbortedOperationError(new Error('boom'))).toBe(false);
expect(isAbortedOperationError('aborted')).toBe(false);
expect(isAbortedOperationError(null)).toBe(false);
expect(isAbortedOperationError(undefined)).toBe(false);
});
});