When handling failures, ensure you (a) don’t lose the real root cause, (b) never introduce new exceptions while trying to report one, and (c) keep graceful degradation both implemented and tested.

Apply these rules:

Example pattern (scope-safe + preserve cause):

function deadlineError(lastError) {
  return new Error(
    `Model generation time budget exhausted: ${lastError?.message ?? 'unknown error'}`,
    { cause: lastError },
  );
}

let lastError;
for (;;) {
  if (Date.now() >= deadline) throw deadlineError(lastError);
  try {
    // ...
  } catch (e) {
    lastError = e;
    // retry / backoff
  }
}

Checklist for review: 1) Are all error sources checked (not just stdout/text)? 2) Can any error-reporting path throw a new exception (scope/ReferenceError)? 3) Do wrapped errors include { cause }? 4) Are control-flow decisions based on stable identifiers (constants), not rewordable strings? 5) Are fallback/best-effort behaviors covered by assertions in tests? 6) Is error-message construction centralized to avoid drift?