• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

semperai / amica-personas / 18364971839

09 Oct 2025 03:52AM UTC coverage: 27.166% (-0.5%) from 27.703%
18364971839

push

github

web-flow
Merge pull request #39 from kasumi-1/etcimprov-fixed

Etcimprov fixed

1425 of 1807 branches covered (78.86%)

Branch coverage included in aggregate %.

1982 of 4805 new or added lines in 67 files covered. (41.25%)

40 existing lines in 19 files now uncovered.

7729 of 31889 relevant lines covered (24.24%)

1074.45 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

96.05
/api/src/utils/fetchWithRetry.ts
1
import { env } from "@/utils/envConfig";
1✔
2

3
const TRACK_N = 10;
1✔
4
const speed = new Map<string, number[]>();
1✔
5

6
export async function fetchWithRetry(
19✔
7
  urls: string | string[],
19✔
8
  options: any,
19✔
9
  retries = env.MAX_RETRIES,
19✔
10
): Promise<Response> {
19✔
11
  let url = "";
19✔
12
  if (typeof urls === "string") {
19✔
13
    url = urls;
18✔
14
  } else {
19✔
15
    url = urls[0];
1✔
16
  }
1✔
17

18
  try {
19✔
19
    const start = Date.now();
19✔
20
    const response = await fetch(url, options);
19✔
21
    const duration = Date.now() - start;
15✔
22

23
    if (!speed.has(url)) {
19✔
24
      speed.set(url, [duration]);
2✔
25
    } else {
19✔
26
      speed.get(url)!.push(duration);
13✔
27
      if (speed.get(url)!.length > TRACK_N) {
13✔
28
        speed.get(url)!.shift();
4✔
29
      }
4✔
30
    }
13✔
31

32
    const averageSpeed = speed.get(url)!.reduce((a, b) => a + b) / speed.get(url)!.length;
15✔
33

34
    console.log(`Request to ${url} took ${duration}ms (average: ${averageSpeed}ms)`);
15✔
35
    if (!response.ok) {
19✔
36
      // Try to get error details from response body
37
      let errorDetails = "";
10✔
38
      try {
10✔
39
        const errorBody = await response.text();
10✔
40
        errorDetails = errorBody ? `: ${errorBody}` : "";
10!
41
      } catch {
10!
42
        // Ignore errors reading response body
NEW
43
      }
×
44

45
      const error = new Error(`HTTP error! status: ${response.status}${errorDetails}`);
10✔
46
      // Only retry on 5xx server errors, not 4xx client errors
47
      if (response.status >= 500 && retries > 0) {
10✔
48
        console.log(`Retrying ${url} attempts left: ${retries - 1} (server error ${response.status})`);
5✔
49
        await new Promise((resolve) => setTimeout(resolve, env.RETRY_DELAY));
5✔
50
        return fetchWithRetry(url, options, retries - 1);
5✔
51
      }
5✔
52
      throw error;
5✔
53
    }
5✔
54
    return response;
5✔
55
  } catch (error) {
19✔
56
    // Retry on network errors (not HTTP errors)
57
    if (retries > 0 && error instanceof Error && !error.message.startsWith("HTTP error!")) {
9✔
58
      console.log(`Retrying ${url} attempts left: ${retries - 1} (network error)`);
3✔
59
      await new Promise((resolve) => setTimeout(resolve, env.RETRY_DELAY));
3✔
60
      return fetchWithRetry(url, options, retries - 1);
3✔
61
    } else {
9✔
62
      throw error;
6✔
63
    }
6✔
64
  }
9✔
65
}
19✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc