From dcae231b524a361681166bf51ea93c289da50b5d Mon Sep 17 00:00:00 2001 From: QLHazyCoder <2825305047@qq.com> Date: Fri, 22 May 2026 05:42:09 +0800 Subject: [PATCH] fix: handle step4 contact-verification server error --- flows/openai/content/openai-auth.js | 33 ++++++- tests/step4-split-code-submit.test.js | 135 ++++++++++++++++++++++++++ 2 files changed, 167 insertions(+), 1 deletion(-) diff --git a/flows/openai/content/openai-auth.js b/flows/openai/content/openai-auth.js index 013b242..2658fd1 100644 --- a/flows/openai/content/openai-auth.js +++ b/flows/openai/content/openai-auth.js @@ -329,10 +329,23 @@ function getContactVerificationServerErrorText() { return combined || 'OpenAI contact-verification page returned HTTP ERROR 500 after resend.'; } +function buildContactVerificationServerError(errorText = '') { + const serverErrorPrefix = typeof PHONE_RESEND_SERVER_ERROR_PREFIX === 'string' + ? PHONE_RESEND_SERVER_ERROR_PREFIX + : 'PHONE_RESEND_SERVER_ERROR::'; + const resolvedText = String(errorText || '').trim() + || 'OpenAI contact-verification 页面返回 HTTP ERROR 500。'; + return new Error( + resolvedText.startsWith(serverErrorPrefix) + ? resolvedText + : `${serverErrorPrefix}${resolvedText}` + ); +} + function throwIfContactVerificationServerError() { const serverErrorText = getContactVerificationServerErrorText(); if (serverErrorText) { - throw new Error(`${PHONE_RESEND_SERVER_ERROR_PREFIX}${serverErrorText}`); + throw buildContactVerificationServerError(serverErrorText); } } @@ -4739,6 +4752,16 @@ function inspectSignupVerificationState() { }; } + const contactVerificationServerErrorText = typeof getContactVerificationServerErrorText === 'function' + ? getContactVerificationServerErrorText() + : ''; + if (contactVerificationServerErrorText) { + return { + state: 'contact_verification_server_error', + serverErrorText: contactVerificationServerErrorText, + }; + } + if (typeof isPhoneVerificationPageReady === 'function' && isPhoneVerificationPageReady()) { return { state: 'verification', @@ -4782,6 +4805,7 @@ async function waitForSignupVerificationTransition(timeout = 5000) { snapshot.state === 'step5' || snapshot.state === 'logged_in_home' || snapshot.state === 'verification' + || snapshot.state === 'contact_verification_server_error' || snapshot.state === 'error' || snapshot.state === 'email_exists' ) { @@ -4888,6 +4912,13 @@ async function prepareSignupVerificationFlow(payload = {}, timeout = 30000) { throw new Error('当前邮箱已存在,需要重新开始新一轮。'); } + if (snapshot.state === 'contact_verification_server_error') { + const serverErrorText = String(snapshot.serverErrorText || '').trim() + || 'OpenAI contact-verification 页面返回 HTTP ERROR 500。'; + log(`${prepareLogLabel}:检测到 contact-verification 500 错误页,当前轮直接报错。`, 'warn'); + throw buildContactVerificationServerError(serverErrorText); + } + if (snapshot.state === 'error') { if (snapshot.userAlreadyExistsBlocked) { throw createSignupUserAlreadyExistsError(); diff --git a/tests/step4-split-code-submit.test.js b/tests/step4-split-code-submit.test.js index 63f0638..f39c0d9 100644 --- a/tests/step4-split-code-submit.test.js +++ b/tests/step4-split-code-submit.test.js @@ -372,6 +372,7 @@ function getActionText(element) { return element?.textContent || ''; } function getPageTextSnapshot() { return document.body.textContent; } ${extractFunction('getContactVerificationServerErrorText')} +${extractFunction('buildContactVerificationServerError')} ${extractFunction('throwIfContactVerificationServerError')} ${extractFunction('resendVerificationCode')} @@ -946,6 +947,52 @@ return { assert.equal(snapshot.targetChecks >= 1, true); }); +test('inspectSignupVerificationState recognizes contact-verification HTTP 500 as explicit server error state', () => { + const api = new Function(` +const location = { + href: 'https://auth.openai.com/contact-verification', + pathname: '/contact-verification', +}; +const document = { + title: "This page isn't working", + body: { + textContent: 'auth.openai.com is currently unable to handle this request. HTTP ERROR 500', + innerText: 'auth.openai.com is currently unable to handle this request. HTTP ERROR 500', + }, + querySelector() { return null; }, + querySelectorAll() { return []; }, +}; +const CONTACT_VERIFICATION_SERVER_ERROR_PATTERN = /this\\s+page\\s+isn['’]?t\\s+working|currently\\s+unable\\s+to\\s+handle\\s+this\\s+request|http\\s+error\\s+500|500\\s+internal\\s+server\\s+error/i; + +function isStep5Ready() { return false; } +function isSignupProfilePageUrl() { return false; } +function isLikelyLoggedInChatgptHomeUrl() { return false; } +function isSignupPasswordErrorPage() { return false; } +function getSignupPasswordTimeoutErrorPageState() { return null; } +function isPhoneVerificationPageReady() { return false; } +function isVerificationPageStillVisible() { return false; } +function isSignupEmailAlreadyExistsPage() { return false; } +function getSignupPasswordInput() { return null; } +function getSignupPasswordSubmitButton() { return null; } +function getSignupPasswordFieldErrorText() { return ''; } +function getPageTextSnapshot() { return document.body.textContent; } + +${extractFunction('getContactVerificationServerErrorText')} +${extractFunction('getStep4PostVerificationState')} +${extractFunction('inspectSignupVerificationState')} + +return { + run() { + return inspectSignupVerificationState(); + }, +}; +`)(); + + const result = api.run(); + assert.equal(result.state, 'contact_verification_server_error'); + assert.match(result.serverErrorText, /HTTP ERROR 500/i); +}); + test('prepareSignupVerificationFlow stops immediately when password page shows phone/password mismatch', async () => { const api = new Function(` const logs = []; @@ -1035,6 +1082,94 @@ return { assert.equal(result.logs.some(({ message }) => /检测到密码页报错/.test(message)), true); }); +test('prepareSignupVerificationFlow stops immediately when page lands on contact-verification HTTP 500', async () => { + const api = new Function(` +const logs = []; +let now = 0; +const PHONE_RESEND_SERVER_ERROR_PREFIX = 'PHONE_RESEND_SERVER_ERROR::'; +const CONTACT_VERIFICATION_SERVER_ERROR_PATTERN = /this\\s+page\\s+isn['’]?t\\s+working|currently\\s+unable\\s+to\\s+handle\\s+this\\s+request|http\\s+error\\s+500|500\\s+internal\\s+server\\s+error/i; + +Date.now = () => now; + +function throwIfStopped() {} +function log(message, level = 'info') { logs.push({ message, level }); } +async function sleep(ms = 0) { now += ms || 200; } +function isVisibleElement() { return true; } +function isActionEnabled() { return true; } +function getActionText(el) { return el?.textContent || ''; } +function getCurrentAuthRetryPageState() { return null; } +function isPhoneVerificationPageReady() { return false; } +function findResendVerificationCodeTrigger() { return null; } +function isEmailVerificationPage() { return false; } +function getPageTextSnapshot() { return document.body.textContent; } +function getVerificationCodeTarget() { return null; } +function is405MethodNotAllowedPage() { return false; } +async function recoverCurrentAuthRetryPage() {} +function createSignupUserAlreadyExistsError() { return new Error('user already exists'); } +function getSignupPasswordInput() { return null; } +function getSignupPasswordSubmitButton() { return null; } +function isSignupEmailAlreadyExistsPage() { return false; } +function isSignupPasswordErrorPage() { return false; } +function getSignupPasswordTimeoutErrorPageState() { return null; } +function isStep5Ready() { return false; } +function humanPause() {} +function fillInput() {} +function logSignupPasswordDiagnostics() {} +function createSignupPhonePasswordMismatchError(detailText = '') { + return new Error('SIGNUP_PHONE_PASSWORD_MISMATCH::' + detailText); +} + +const location = { + href: 'https://auth.openai.com/contact-verification', + pathname: '/contact-verification', +}; +const document = { + readyState: 'complete', + title: "This page isn't working", + body: { + textContent: 'auth.openai.com is currently unable to handle this request. HTTP ERROR 500', + innerText: 'auth.openai.com is currently unable to handle this request. HTTP ERROR 500', + }, + querySelector() { + return null; + }, + querySelectorAll() { + return []; + }, +}; + +${extractFunction('getContactVerificationServerErrorText')} +${extractFunction('buildContactVerificationServerError')} +${extractFunction('isSignupVerificationPageInteractiveReady')} +${extractFunction('isVerificationPageStillVisible')} +${extractFunction('isSignupProfilePageUrl')} +${extractFunction('isLikelyLoggedInChatgptHomeUrl')} +${extractFunction('getStep4PostVerificationState')} +${extractFunction('inspectSignupVerificationState')} +${extractFunction('waitForSignupVerificationTransition')} +${extractFunction('prepareSignupVerificationFlow')} + +return { + async run() { + try { + await prepareSignupVerificationFlow({ + prepareLogLabel: '步骤 4 执行', + }, 10000); + return { threw: false, logs }; + } catch (error) { + return { threw: true, error: error.message, logs }; + } + }, +}; +`)(); + + const result = await api.run(); + + assert.equal(result.threw, true); + assert.match(result.error, /^PHONE_RESEND_SERVER_ERROR::This page isn't working/); + assert.equal(result.logs.some(({ message }) => /contact-verification 500 错误页/.test(message)), true); +}); + test('prepareSignupVerificationFlow stops immediately when password page shows phone already exists error', async () => { const api = new Function(` const logs = [];