fix(client/payment): switchMethod 补 catch-all 兜网络/超时错(与 start/resume 对齐)防卡 awaitingPayment

switchMethod 的首个 retry() 调用只 catch AuthApiException,网络/超时/未知异常会穿出到
无 try/catch 的 _pickAndSwitch,UI 卡在 awaitingPayment 无任何提示。补一个 catch-all,
与 start()/resume() 同一处理形状落 failed 相位(自动经 build() 切到 _failed() 呈现);
payment_page.dart 的 _pickAndSwitch 再加一层防御性 try/catch + toast,防任何逃逸异常
变成无提示的 unhandled rejection。补单测覆盖非 Auth 异常路径。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P9G7E3wmAYL9KeYCVZVsqu
This commit is contained in:
wangjia
2026-07-13 15:53:30 +08:00
parent 3acd3ca59d
commit 301e13f477
3 changed files with 31 additions and 1 deletions
+14
View File
@@ -105,6 +105,20 @@ void main() {
expect(c.read(paymentFlowProvider).order?.orderNo, 'pay2');
});
test('switchMethod 遇非 Auth 异常(网络/超时)→ 落 failed 兜底,不卡 awaitingPayment', () async {
final api = _FakePaymentApi();
final c = _container(api);
final ctl = c.read(paymentFlowProvider.notifier);
await ctl.start(item, 'crypto');
api.retryError = Exception('network timeout');
await ctl.switchMethod('alipay');
expect(c.read(paymentFlowProvider).phase, PaymentPhase.failed);
expect(c.read(paymentFlowProvider).errorZh, isNotNull);
expect(c.read(paymentFlowProvider).errorZh, isNotEmpty);
expect(c.read(paymentFlowProvider).errorEn, isNotNull);
expect(c.read(paymentFlowProvider).errorEn, isNotEmpty);
});
test('resume() 成功 → retry 恢复原单会话(不新下单),phase=awaitingPayment', () async {
final api = _FakePaymentApi();
final c = _container(api);