upload current sources

This commit is contained in:
2026-09-16 01:47:28 -07:00
commit f8b45ea4a5
109 changed files with 26012 additions and 0 deletions
+49
View File
@@ -0,0 +1,49 @@
/**
* Public error phrases — the ONLY text derived from a caught error that may
* reach a wire response (`HealthStatus.poller.lastError`, `SyncRun.error`,
* `SyncObjectProgress.error`; governed contract docs/api/worker.openapi.json).
*
* Allowlist keyed on error class / upstream HTTP status, mirroring the 502
* mapping in server.ts: a raw `err.message` is never copied out, because
* Arena error bodies can echo request data (and, for the future S/4HANA leg,
* OData error payloads can echo business data). Anything not on the list gets
* the unclassified phrase; the full error stays in the worker log, which is
* where diagnosis belongs (index.ts logs `{ name, status, message }`).
*
* `TimeoutError` is what Node's fetch rejects with when the request's
* `AbortSignal.timeout(...)` fires (measured on this box, Node 24.15.0,
* 2026-09-14: `name=TimeoutError`, a DOMException).
*/
import { ArenaApiError } from '../arena/session.js';
import { IngestBufferFullError } from '../poller/arenaDeltaPoll.js';
export const UNCLASSIFIED_ERROR_PHRASE = 'Unclassified worker error; see worker logs.';
export const INGEST_BUFFER_FULL_PHRASE = 'Ingest buffer full at poll time.';
export const ARENA_TIMEOUT_PHRASE = 'Upstream Arena PLM request timed out.';
export const ARENA_MALFORMED_PHRASE = 'Upstream Arena PLM response was malformed.';
export function arenaStatusPhrase(status: number): string {
// A 2xx ArenaApiError is a response we could not interpret (e.g. login
// answered 200 without an arenaSessionId), not an upstream failure code.
if (status >= 200 && status < 300) return ARENA_MALFORMED_PHRASE;
return `Upstream Arena PLM request failed (HTTP ${status}).`;
}
export function publicErrorPhrase(err: unknown): string {
if (err instanceof ArenaApiError) return arenaStatusPhrase(err.status);
if (err instanceof IngestBufferFullError) return INGEST_BUFFER_FULL_PHRASE;
if (hasName(err, 'TimeoutError')) return ARENA_TIMEOUT_PHRASE;
return UNCLASSIFIED_ERROR_PHRASE;
}
/** Log-safe summary of an error: class name, message, and upstream status if any. */
export function describeErrorForLog(err: unknown): { name: string; message: string; status?: number } {
if (err instanceof ArenaApiError) return { name: err.name, message: err.message, status: err.status };
if (err instanceof Error) return { name: err.name, message: err.message };
return { name: typeof err, message: String(err) };
}
function hasName(err: unknown, name: string): boolean {
return typeof err === 'object' && err !== null && 'name' in err && (err as { name: unknown }).name === name;
}