gpt-engineer-app[bot] commited on
Commit
49e5894
·
2 Parent(s): 5c563fc773640b

Added retry with backoff

Browse files

X-Lovable-Edit-ID: edt-285825be-47a4-4304-9a3a-64491f0fcf1e

Files changed (1) hide show
  1. src/server/incidents.functions.ts +31 -13
src/server/incidents.functions.ts CHANGED
@@ -84,21 +84,39 @@ export const analyzeIncident = createServerFn({ method: "POST" })
84
  try {
85
  const userContent = `INCIDENT TITLE: ${incident.title}\nSOURCE TYPE: ${incident.source_type}\nFILE: ${incident.file_name ?? "(none)"}\n\n--- RAW INPUT ---\n${incident.raw_text ?? "(no text content provided)"}`;
86
 
87
- const resp = await fetch(aiChatCompletionsUrl(), {
88
- method: "POST",
89
- headers: aiAuthHeaders(),
90
- body: JSON.stringify({
91
- model: resolveModel("google/gemini-2.5-flash"),
92
- messages: [
93
- { role: "system", content: SYSTEM_PROMPT },
94
- { role: "system", content: AV_KNOWLEDGE_BASE },
95
- { role: "user", content: userContent },
96
- ],
97
- tools: [analysisTool],
98
- tool_choice: { type: "function", function: { name: "submit_analysis" } },
99
- }),
100
  });
101
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
  if (!resp.ok) {
103
  const text = await resp.text();
104
  if (resp.status === 429) throw new Error("Rate limit reached. Try again shortly.");
 
84
  try {
85
  const userContent = `INCIDENT TITLE: ${incident.title}\nSOURCE TYPE: ${incident.source_type}\nFILE: ${incident.file_name ?? "(none)"}\n\n--- RAW INPUT ---\n${incident.raw_text ?? "(no text content provided)"}`;
86
 
87
+ const requestBody = JSON.stringify({
88
+ model: resolveModel("google/gemini-2.5-flash"),
89
+ messages: [
90
+ { role: "system", content: SYSTEM_PROMPT },
91
+ { role: "system", content: AV_KNOWLEDGE_BASE },
92
+ { role: "user", content: userContent },
93
+ ],
94
+ tools: [analysisTool],
95
+ tool_choice: { type: "function", function: { name: "submit_analysis" } },
 
 
 
 
96
  });
97
 
98
+ // Retry transient network failures (SSR worker occasionally drops the
99
+ // first outbound fetch). Up to 3 attempts with exponential backoff.
100
+ let resp: Response | undefined;
101
+ let lastErr: unknown;
102
+ for (let attempt = 0; attempt < 3; attempt++) {
103
+ try {
104
+ resp = await fetch(aiChatCompletionsUrl(), {
105
+ method: "POST",
106
+ headers: aiAuthHeaders(),
107
+ body: requestBody,
108
+ });
109
+ break;
110
+ } catch (e) {
111
+ lastErr = e;
112
+ await new Promise((r) => setTimeout(r, 400 * (attempt + 1)));
113
+ }
114
+ }
115
+ if (!resp) {
116
+ const msg = lastErr instanceof Error ? lastErr.message : String(lastErr);
117
+ throw new Error(`Could not reach AI gateway: ${msg}`);
118
+ }
119
+
120
  if (!resp.ok) {
121
  const text = await resp.text();
122
  if (resp.status === 429) throw new Error("Rate limit reached. Try again shortly.");