Skip to content

Commit 86f73c3

Browse files
authored
No timeout for fetch being used by loadGLB, loadOBJ ... (Add the abortcontroller pattern to timeout after 30s) (#142)
1 parent ba35f92 commit 86f73c3

6 files changed

Lines changed: 48 additions & 10 deletions

File tree

lib/loaders/fetch-with-timeout.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import type { AuthHeaders } from "../types"
2+
3+
export const DEFAULT_FETCH_TIMEOUT_MS = 30_000
4+
5+
export async function fetchWithTimeout(
6+
url: string,
7+
{
8+
authHeaders,
9+
timeoutMs = DEFAULT_FETCH_TIMEOUT_MS,
10+
}: {
11+
authHeaders?: AuthHeaders
12+
timeoutMs?: number
13+
} = {},
14+
): Promise<Response> {
15+
const controller = new AbortController()
16+
let timedOut = false
17+
18+
const timeoutId = setTimeout(() => {
19+
timedOut = true
20+
controller.abort()
21+
}, timeoutMs)
22+
23+
try {
24+
return await fetch(url, {
25+
headers: authHeaders,
26+
signal: controller.signal,
27+
})
28+
} catch (error) {
29+
if (timedOut) {
30+
throw new Error(`Request timed out after ${timeoutMs}ms: ${url}`)
31+
}
32+
throw error
33+
} finally {
34+
clearTimeout(timeoutId)
35+
}
36+
}

lib/loaders/glb.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,13 @@ import type {
77
STLMesh,
88
Triangle,
99
} from "../types"
10-
import {
11-
COORDINATE_TRANSFORMS,
12-
transformTriangles,
13-
} from "../utils/coordinate-transform"
10+
import { transformTriangles } from "../utils/coordinate-transform"
1411
import {
1512
applyNodeTransform,
1613
applyQuaternion,
1714
buildMeshTransforms,
1815
} from "../utils/gltf-node-transforms"
16+
import { fetchWithTimeout } from "./fetch-with-timeout"
1917
import { resolveModelUrl } from "./resolve-model-url"
2018

2119
const glbCache = new Map<string, STLMesh | OBJMesh>()
@@ -37,7 +35,7 @@ export async function loadGLB({
3735
return glbCache.get(cacheKey)!
3836
}
3937

40-
const response = await fetch(resolvedUrl, { headers: authHeaders })
38+
const response = await fetchWithTimeout(resolvedUrl, { authHeaders })
4139
if (!response.ok) {
4240
throw new Error(
4341
`Failed to fetch GLB: ${response.status} ${response.statusText}`,

lib/loaders/gltf.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,15 @@ import type {
44
OBJMesh,
55
STLMesh,
66
} from "../types"
7+
import { fetchWithTimeout } from "./fetch-with-timeout"
78
import { parseGLB } from "./glb"
89
import { resolveModelUrl } from "./resolve-model-url"
910

1011
async function fetchAsArrayBuffer(
1112
url: string,
1213
authHeaders?: AuthHeaders,
1314
): Promise<ArrayBuffer> {
14-
const response = await fetch(url, { headers: authHeaders })
15+
const response = await fetchWithTimeout(url, { authHeaders })
1516
if (!response.ok) {
1617
throw new Error(`Failed to fetch ${url}: ${response.statusText}`)
1718
}
@@ -33,7 +34,7 @@ export async function fetchGltfAndConvertToGlb(
3334
url: string,
3435
authHeaders?: AuthHeaders,
3536
): Promise<ArrayBuffer> {
36-
const gltfResponse = await fetch(url, { headers: authHeaders })
37+
const gltfResponse = await fetchWithTimeout(url, { authHeaders })
3738
if (!gltfResponse.ok) {
3839
throw new Error(`Failed to fetch glTF file: ${gltfResponse.statusText}`)
3940
}

lib/loaders/obj.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
COORDINATE_TRANSFORMS,
1212
transformTriangles,
1313
} from "../utils/coordinate-transform"
14+
import { fetchWithTimeout } from "./fetch-with-timeout"
1415
import { resolveModelUrl } from "./resolve-model-url"
1516

1617
const objCache = new Map<string, OBJMesh>()
@@ -31,7 +32,7 @@ export async function loadOBJ({
3132
if (objCache.has(cacheKey)) {
3233
return objCache.get(cacheKey)!
3334
}
34-
const response = await fetch(resolvedUrl, { headers: authHeaders })
35+
const response = await fetchWithTimeout(resolvedUrl, { authHeaders })
3536
const text = await response.text()
3637
const mesh = parseOBJ(text, transform)
3738
objCache.set(cacheKey, mesh)

lib/loaders/step.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
COORDINATE_TRANSFORMS,
1212
transformTriangles,
1313
} from "../utils/coordinate-transform"
14+
import { fetchWithTimeout } from "./fetch-with-timeout"
1415
import { resolveModelUrl } from "./resolve-model-url"
1516

1617
const stepCache = new Map<string, STLMesh | OBJMesh>()
@@ -61,7 +62,7 @@ export async function loadSTEP({
6162
return stepCache.get(cacheKey)!
6263
}
6364

64-
const response = await fetch(resolvedUrl, { headers: authHeaders })
65+
const response = await fetchWithTimeout(resolvedUrl, { authHeaders })
6566
if (!response.ok) {
6667
throw new Error(
6768
`Failed to fetch STEP file: ${response.status} ${response.statusText}`,

lib/loaders/stl.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
COORDINATE_TRANSFORMS,
1010
transformTriangles,
1111
} from "../utils/coordinate-transform"
12+
import { fetchWithTimeout } from "./fetch-with-timeout"
1213
import { resolveModelUrl } from "./resolve-model-url"
1314

1415
const stlCache = new Map<string, STLMesh>()
@@ -30,7 +31,7 @@ export async function loadSTL({
3031
return stlCache.get(cacheKey)!
3132
}
3233

33-
const response = await fetch(resolvedUrl, { headers: authHeaders })
34+
const response = await fetchWithTimeout(resolvedUrl, { authHeaders })
3435
const buffer = await response.arrayBuffer()
3536
const mesh = parseSTL(buffer, transform)
3637
stlCache.set(cacheKey, mesh)

0 commit comments

Comments
 (0)