feat: 添加 GPC 任务过期状态处理,增强任务执行的稳定性和错误提示

This commit is contained in:
QLHazyCoder
2026-05-10 02:29:54 +08:00
parent 35bf6a2c32
commit b02b375449
2 changed files with 127 additions and 1 deletions
@@ -85,6 +85,7 @@ function createExecutorHarness({
markCurrentRegistrationAccountUsed = async () => {},
probeIpProxyExit = null,
onSetState = null,
sleepWithStop = null,
submitRedirectUrl = 'https://www.paypal.com/checkoutnow',
}) {
const api = loadPlusCheckoutBillingModule();
@@ -166,7 +167,7 @@ function createExecutorHarness({
await onSetState(updates, events);
}
},
sleepWithStop: async (ms) => events.sleeps.push(ms),
sleepWithStop: sleepWithStop || (async (ms) => events.sleeps.push(ms)),
waitForTabCompleteUntilStopped: async () => checkoutTab,
waitForTabUrlMatchUntilStopped: async (tabId, matcher) => {
events.waitedUrls.push({ tabId });
@@ -1016,6 +1017,70 @@ test('GPC billing logs checkout order stage in Chinese', async () => {
assert.equal(events.logs.some((entry) => /checkout_order_start/.test(entry.message)), false);
});
test('GPC billing fails repeated checkout stage as stale so auto-run can recreate task', async () => {
const originalNow = Date.now;
let now = 1710000000000;
const fetchCalls = [];
const { events, executor } = createExecutorHarness({
frames: [],
stateByFrame: {},
sleepWithStop: async (ms) => {
events.sleeps.push(ms);
now += ms;
},
fetchImpl: async (url, options = {}) => {
fetchCalls.push({ url, options });
if (url === 'https://gpc.qlhazycoder.top/api/gp/tasks/task_stale') {
return {
ok: true,
status: 200,
json: async () => createGpcTaskResponse({
task_id: 'task_stale',
phone_mode: 'auto',
status: 'active',
status_text: '处理中',
remote_stage: 'checkout_order_start',
api_waiting_for: '',
}),
};
}
if (url.endsWith('/api/gp/tasks/task_stale/stop')) {
return {
ok: true,
status: 200,
json: async () => createGpcTaskResponse({
task_id: 'task_stale',
status: 'discarded',
status_text: '已停止',
}),
};
}
throw new Error(`unexpected url: ${url}`);
},
});
Date.now = () => now;
try {
await assert.rejects(
() => executor.executePlusCheckoutBilling({
plusPaymentMethod: 'gpc-helper',
plusCheckoutSource: 'gpc-helper',
gopayHelperTaskId: 'task_stale',
gopayHelperPhoneMode: 'auto',
gopayHelperApiUrl: 'https://gpc.qlhazycoder.top/',
gopayHelperApiKey: 'gpc_auto',
gopayHelperTaskStaleSeconds: 15,
}),
/GPC_TASK_ENDED::GPC 任务状态超过 15 秒无进展(创建订单),请重新创建任务。/
);
} finally {
Date.now = originalNow;
}
assert.equal(fetchCalls.some((call) => call.url.endsWith('/api/gp/tasks/task_stale/stop')), true);
assert.equal(events.logs.some((entry) => entry.message === '步骤 7GPC 任务状态:创建订单'), true);
});
test('GPC billing reads SMS OTP from local helper for sms_otp_wait', async () => {
const fetchCalls = [];
let pollCount = 0;