fix: expose web probe auth retry summary
This commit is contained in:
@@ -3810,7 +3810,8 @@ async function authenticate(browserContext) {
|
||||
async function authenticateWithApiRetries(browserContext) {
|
||||
const loginUrl = new URL("/auth/login", baseUrl).toString();
|
||||
const attempts = [];
|
||||
for (let attempt = 1; attempt <= 3; attempt += 1) {
|
||||
const maxAttempts = 3;
|
||||
for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
|
||||
try {
|
||||
const response = await browserContext.request.post(loginUrl, {
|
||||
data: { username, password },
|
||||
@@ -3819,10 +3820,12 @@ async function authenticateWithApiRetries(browserContext) {
|
||||
});
|
||||
const summary = await responseSummary(response);
|
||||
const cookieState = await readAuthCookieState(browserContext);
|
||||
const retryable = isRetryableAuthStatus(response.status());
|
||||
const item = {
|
||||
attempt,
|
||||
method: "api",
|
||||
...summary,
|
||||
retryable,
|
||||
cookiePresent: cookieState.cookiePresent,
|
||||
cookieNames: cookieState.cookieNames,
|
||||
};
|
||||
@@ -3837,21 +3840,24 @@ async function authenticateWithApiRetries(browserContext) {
|
||||
cookiePresent: true,
|
||||
cookieNames: cookieState.cookieNames,
|
||||
attempts,
|
||||
retryCount: attempt - 1,
|
||||
fallbackUsed: false,
|
||||
valuesRedacted: true,
|
||||
};
|
||||
}
|
||||
if (response.status() < 500 && response.status() !== 429) break;
|
||||
if (!retryable) break;
|
||||
} catch (error) {
|
||||
attempts.push({
|
||||
attempt,
|
||||
method: "api",
|
||||
status: 0,
|
||||
statusText: "request-error",
|
||||
retryable: true,
|
||||
error: error instanceof Error ? error.message : String(error),
|
||||
cookiePresent: false,
|
||||
});
|
||||
}
|
||||
if (attempt < 3) await sleep(300 * attempt);
|
||||
if (attempt < maxAttempts) await sleep(300 * attempt);
|
||||
}
|
||||
const cookieState = await readAuthCookieState(browserContext);
|
||||
const last = attempts[attempts.length - 1] ?? null;
|
||||
@@ -3864,6 +3870,9 @@ async function authenticateWithApiRetries(browserContext) {
|
||||
cookiePresent: cookieState.cookiePresent,
|
||||
cookieNames: cookieState.cookieNames,
|
||||
attempts,
|
||||
retryCount: retryCountFromAttempts(attempts),
|
||||
fallbackUsed: false,
|
||||
retryable: authAttemptsRetryable(attempts),
|
||||
errorSummary: last,
|
||||
valuesRedacted: true,
|
||||
};
|
||||
@@ -3896,6 +3905,9 @@ async function authenticateWithFormFallback(browserContext, apiAuth) {
|
||||
cookiePresent: cookieState.cookiePresent,
|
||||
cookieNames: cookieState.cookieNames,
|
||||
attempts: apiAuth.attempts,
|
||||
retryCount: apiAuth.retryCount ?? retryCountFromAttempts(apiAuth.attempts),
|
||||
fallbackUsed: true,
|
||||
retryable: apiAuth.retryable === true,
|
||||
apiErrorSummary: apiAuth.errorSummary,
|
||||
fallback,
|
||||
valuesRedacted: true,
|
||||
@@ -3938,6 +3950,9 @@ async function authenticateWithFormFallback(browserContext, apiAuth) {
|
||||
cookiePresent: cookieState.cookiePresent,
|
||||
cookieNames: cookieState.cookieNames,
|
||||
attempts: apiAuth.attempts,
|
||||
retryCount: apiAuth.retryCount ?? retryCountFromAttempts(apiAuth.attempts),
|
||||
fallbackUsed: true,
|
||||
retryable: apiAuth.retryable === true,
|
||||
apiErrorSummary: apiAuth.errorSummary,
|
||||
fallback,
|
||||
valuesRedacted: true,
|
||||
@@ -3955,6 +3970,9 @@ async function authenticateWithFormFallback(browserContext, apiAuth) {
|
||||
cookiePresent: cookieState.cookiePresent,
|
||||
cookieNames: cookieState.cookieNames,
|
||||
attempts: apiAuth.attempts,
|
||||
retryCount: apiAuth.retryCount ?? retryCountFromAttempts(apiAuth.attempts),
|
||||
fallbackUsed: true,
|
||||
retryable: apiAuth.retryable === true,
|
||||
apiErrorSummary: apiAuth.errorSummary,
|
||||
fallback,
|
||||
valuesRedacted: true,
|
||||
@@ -4451,6 +4469,19 @@ function boundedInteger(raw, fallback, min, max) {
|
||||
return Math.max(min, Math.min(max, value));
|
||||
}
|
||||
|
||||
function isRetryableAuthStatus(status) {
|
||||
return status === 0 || status === 429 || status >= 500;
|
||||
}
|
||||
|
||||
function retryCountFromAttempts(attempts) {
|
||||
return Math.max(0, Array.isArray(attempts) ? attempts.length - 1 : 0);
|
||||
}
|
||||
|
||||
function authAttemptsRetryable(attempts) {
|
||||
if (!Array.isArray(attempts) || attempts.length === 0) return false;
|
||||
return attempts.some((attempt) => attempt && typeof attempt === "object" && attempt.retryable === true);
|
||||
}
|
||||
|
||||
async function responseSummary(response) {
|
||||
const status = response.status();
|
||||
let bodyPreview = null;
|
||||
@@ -4498,22 +4529,52 @@ function sleep(ms) {
|
||||
}
|
||||
|
||||
function publicAuth(value) {
|
||||
const retryCount = Number.isInteger(value.retryCount) ? value.retryCount : retryCountFromAttempts(value.attempts);
|
||||
const transientObserved = authAttemptsRetryable(value.attempts);
|
||||
const ok = value.ok === true;
|
||||
const retryable = ok ? false : value.retryable === true || transientObserved;
|
||||
return {
|
||||
ok: value.ok,
|
||||
ok,
|
||||
method: value.method ?? null,
|
||||
origin: new URL(baseUrl).origin,
|
||||
loginPath: value.loginUrl,
|
||||
status: value.status,
|
||||
statusText: value.statusText,
|
||||
cookiePresent: value.cookiePresent,
|
||||
cookieNames: value.cookieNames,
|
||||
attempts: value.attempts ?? null,
|
||||
retryCount,
|
||||
fallbackUsed: value.fallbackUsed === true || value.method === "form-fallback",
|
||||
fallback: value.fallback ?? null,
|
||||
errorSummary: cloneSummary(value.errorSummary ?? value.apiErrorSummary ?? null),
|
||||
degradedReason: ok ? null : "auth-login-failed",
|
||||
retryable,
|
||||
transientObserved,
|
||||
commanderAction: ok
|
||||
? null
|
||||
: retryable
|
||||
? "retry same web-probe command after short backoff; inspect target /auth/login and Cloud Web/API rollout if repeated"
|
||||
: "inspect bootstrap admin credential source and target user state",
|
||||
fingerprint: authSummaryFingerprint(value),
|
||||
username,
|
||||
valuesRedacted: true,
|
||||
};
|
||||
}
|
||||
|
||||
function authSummaryFingerprint(value) {
|
||||
const payload = JSON.stringify({
|
||||
origin: new URL(baseUrl).origin,
|
||||
loginPath: value.loginUrl ?? null,
|
||||
method: value.method ?? null,
|
||||
status: value.status ?? null,
|
||||
statusText: value.statusText ?? null,
|
||||
cookiePresent: value.cookiePresent === true,
|
||||
retryCount: Number.isInteger(value.retryCount) ? value.retryCount : retryCountFromAttempts(value.attempts),
|
||||
fallbackUsed: value.fallbackUsed === true || value.method === "form-fallback",
|
||||
});
|
||||
return "sha256:" + createHash("sha256").update(payload).digest("hex").slice(0, 16);
|
||||
}
|
||||
|
||||
function cloneSummary(value) {
|
||||
if (!value || typeof value !== "object" || Array.isArray(value)) return value ?? null;
|
||||
return { ...value };
|
||||
|
||||
Reference in New Issue
Block a user