fix: save as draft when Gemini 503 exhausts all retries
When API congestion persists after 3 retries + fallback: - Mark exception with [CONGESTION] tag - camera_screen catches it and calls DraftService.saveDraft() - Shows orange snackbar (same UX as offline) instead of red error Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
b3d07f8794
commit
182e498188
|
|
@ -568,8 +568,48 @@ class _CameraScreenState extends ConsumerState<CameraScreen> with SingleTickerPr
|
|||
if (mounted) {
|
||||
Navigator.of(context).pop(); // Close AnalyzingDialog
|
||||
|
||||
// Check for Quota Error to set Lockout
|
||||
if (e.toString().contains('Quota') || e.toString().contains('429')) {
|
||||
final errStr = e.toString();
|
||||
|
||||
// AIサーバー混雑(503)→ ドラフト保存してオフライン時と同じ扱いに
|
||||
if (errStr.contains('[CONGESTION]')) {
|
||||
try {
|
||||
await DraftService.saveDraft(_capturedImages);
|
||||
if (!mounted) return;
|
||||
Navigator.of(context).pop(); // Close camera screen
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
content: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Icon(LucideIcons.cloudOff, color: Colors.white, size: 16),
|
||||
SizedBox(width: 8),
|
||||
Text('AIサーバー混雑', style: TextStyle(fontWeight: FontWeight.bold)),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 4),
|
||||
Text('写真を「解析待ち」として保存しました。'),
|
||||
Text('時間をおいてホーム画面から解析できます。'),
|
||||
],
|
||||
),
|
||||
duration: Duration(seconds: 5),
|
||||
backgroundColor: Colors.orange,
|
||||
),
|
||||
);
|
||||
} catch (_) {
|
||||
// ドラフト保存も失敗した場合のみエラー表示
|
||||
if (!mounted) return;
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(content: Text('解析もドラフト保存も失敗しました。再試行してください。')),
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Quota エラー(429)→ ロックアウト
|
||||
if (errStr.contains('Quota') || errStr.contains('429')) {
|
||||
setState(() {
|
||||
_quotaLockoutTime = DateTime.now().add(const Duration(minutes: 1));
|
||||
});
|
||||
|
|
|
|||
|
|
@ -349,7 +349,8 @@ $extractedText
|
|||
if (isLastAttempt || !is503) {
|
||||
// 最終試行 or 503以外のエラーはそのまま投げる
|
||||
if (is503) {
|
||||
throw Exception('AIサーバーが混雑しています。しばらく待ってから再試行してください。');
|
||||
// [CONGESTION] マーカー付きで投げる → camera_screen でドラフト保存へ
|
||||
throw Exception('[CONGESTION] AIサーバーが混雑しています。解析待ちとして保存します。');
|
||||
}
|
||||
throw Exception('AI解析エラー(Direct): $e');
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue