@@ -111,6 +111,12 @@ async function readCappedResponseBuffer(res: Response, maxResponseBytes: number)
|
111 | 111 | }); |
112 | 112 | } |
113 | 113 | |
| 114 | +async function releaseUnreadResponseBody(res: Response | undefined): Promise<void> { |
| 115 | +if (res?.bodyUsed !== true) { |
| 116 | +await res?.body?.cancel().catch(() => undefined); |
| 117 | +} |
| 118 | +} |
| 119 | + |
114 | 120 | /** |
115 | 121 | * Check if bbernhard container REST API is available. |
116 | 122 | */ |
@@ -120,8 +126,9 @@ export async function containerCheck(
|
120 | 126 | account?: string, |
121 | 127 | ): Promise<{ ok: boolean; status?: number | null; error?: string | null }> { |
122 | 128 | const normalized = normalizeBaseUrl(baseUrl); |
| 129 | +let res: Response | undefined; |
123 | 130 | try { |
124 | | -const res = await fetchWithTimeout(`${normalized}/v1/about`, { method: "GET" }, timeoutMs); |
| 131 | +res = await fetchWithTimeout(`${normalized}/v1/about`, { method: "GET" }, timeoutMs); |
125 | 132 | if (!res.ok) { |
126 | 133 | return { ok: false, status: res.status, error: `HTTP ${res.status}` }; |
127 | 134 | } |
@@ -136,6 +143,8 @@ export async function containerCheck(
|
136 | 143 | status: null, |
137 | 144 | error: err instanceof Error ? err.message : String(err), |
138 | 145 | }; |
| 146 | +} finally { |
| 147 | +await releaseUnreadResponseBody(res); |
139 | 148 | } |
140 | 149 | } |
141 | 150 | |
@@ -253,14 +262,19 @@ export async function containerFetchAttachment(
|
253 | 262 | ): Promise<Buffer | null> { |
254 | 263 | const baseUrl = normalizeBaseUrl(opts.baseUrl); |
255 | 264 | const url = `${baseUrl}/v1/attachments/${encodeURIComponent(attachmentId)}`; |
| 265 | +let res: Response | undefined; |
256 | 266 | |
257 | | -const res = await fetchWithTimeout(url, { method: "GET" }, opts.timeoutMs ?? DEFAULT_TIMEOUT_MS); |
| 267 | +try { |
| 268 | +res = await fetchWithTimeout(url, { method: "GET" }, opts.timeoutMs ?? DEFAULT_TIMEOUT_MS); |
258 | 269 | |
259 | | -if (!res.ok) { |
260 | | -return null; |
261 | | -} |
| 270 | + if (!res.ok) { |
| 271 | + return null; |
| 272 | + } |
262 | 273 | |
263 | | -return readCappedResponseBuffer(res, normalizeMaxResponseBytes(opts.maxResponseBytes)); |
| 274 | +return await readCappedResponseBuffer(res, normalizeMaxResponseBytes(opts.maxResponseBytes)); |
| 275 | +} finally { |
| 276 | +await releaseUnreadResponseBody(res); |
| 277 | +} |
264 | 278 | } |
265 | 279 | |
266 | 280 | /** |
|