v1rtl
v1rtl9mo ago

"A fetch response body was created during the test" when invoking a PUT request in a test?

I'm writing a Deno library for uploading files on IPFS. The code is very simple:
export const uploadCar = async ({ file, url }) => {
const res = await fetch(url, {
method: 'PUT',
body: file,
headers: { 'x-amz-meta-import': 'car' },
})

return res.headers.get('x-amz-meta-cid')!
}
export const uploadCar = async ({ file, url }) => {
const res = await fetch(url, {
method: 'PUT',
body: file,
headers: { 'x-amz-meta-import': 'car' },
})

return res.headers.get('x-amz-meta-cid')!
}
And this is the test file I have:
import { CAREncoderStream, createFileEncoderStream } from 'https://esm.sh/ipfs-car@1.0.0'
import { CID } from 'https://esm.sh/multiformats@12.1.3/cid'

async function streamToBlob(stream: ReadableStream): Promise<Blob> {
const reader = stream.getReader()
const chunks: Uint8Array[] = []

while (true) {
const { done, value } = await reader.read()
if (done) break
chunks.push(value)
}

return new Blob(chunks, { type: 'application/octet-stream' })
}

describe('uploadCar', () => {
it(
'should upload a CAR file',
async () => {
const stream = createFileEncoderStream(new Blob(['Hello ipfs-car!']))
.pipeThrough(
new TransformStream(),
)
.pipeThrough(new CAREncoderStream([placeholderCID]))

const blob = await streamToBlob(stream)

const file = new File([blob], 'file.car')

const cid = await uploadCar({ file, ...args })

assertEquals(cid, 'bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi')
},
)
})
import { CAREncoderStream, createFileEncoderStream } from 'https://esm.sh/ipfs-car@1.0.0'
import { CID } from 'https://esm.sh/multiformats@12.1.3/cid'

async function streamToBlob(stream: ReadableStream): Promise<Blob> {
const reader = stream.getReader()
const chunks: Uint8Array[] = []

while (true) {
const { done, value } = await reader.read()
if (done) break
chunks.push(value)
}

return new Blob(chunks, { type: 'application/octet-stream' })
}

describe('uploadCar', () => {
it(
'should upload a CAR file',
async () => {
const stream = createFileEncoderStream(new Blob(['Hello ipfs-car!']))
.pipeThrough(
new TransformStream(),
)
.pipeThrough(new CAREncoderStream([placeholderCID]))

const blob = await streamToBlob(stream)

const file = new File([blob], 'file.car')

const cid = await uploadCar({ file, ...args })

assertEquals(cid, 'bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi')
},
)
})
When running this test this is what Im getting:
uploadCar ... should upload a CAR file => https://deno.land/std@0.207.0/testing/_test_suite.ts:323:15
error: Leaking resources:
- A fetch response body (rid 18) was created during the test, but not consumed during the test. Consume or close the response body `ReadableStream`, e.g `await resp.text()` or `await resp.body.cancel()`.
uploadCar ... should upload a CAR file => https://deno.land/std@0.207.0/testing/_test_suite.ts:323:15
error: Leaking resources:
- A fetch response body (rid 18) was created during the test, but not consumed during the test. Consume or close the response body `ReadableStream`, e.g `await resp.text()` or `await resp.body.cancel()`.
I couldn't find much info about the issue - what could be a possible fix?
2 Replies
marvinh.
marvinh.9mo ago
This usually happens when you do something like this in the test:
const res = await fetch("..")
assertEquals(res.status, 200)
const res = await fetch("..")
assertEquals(res.status, 200)
There the response body is not consumed. The fix is to consume it by doing something like this.
const res = await fetch("..")
assertEquals(res.status, 200)
await res.text() // consume resposne body
// or
await res.body.cancel()
const res = await fetch("..")
assertEquals(res.status, 200)
await res.text() // consume resposne body
// or
await res.body.cancel()
v1rtl
v1rtl9mo ago
What to do if I'm not returning a response? I tried changing the code to this:
const res = await uploadCar({ bucketName: 'filebase-upload-tests', token: Deno.env.get('FILEBASE_TOKEN')!, file })

assertEquals(res.headers.get('x-amz-meta-cid'), 'bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi')

await res.body?.cancel()
const res = await uploadCar({ bucketName: 'filebase-upload-tests', token: Deno.env.get('FILEBASE_TOKEN')!, file })

assertEquals(res.headers.get('x-amz-meta-cid'), 'bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi')

await res.body?.cancel()
It still errors the same way I made an ugly solution:
await res.body?.cancel()
const fetchResource = Object.keys(Deno.resources()).find((key) =>
Deno.resources()[parseInt(key)] === 'fetchResponse'
)
Deno.close(parseInt(fetchResource!))
await res.body?.cancel()
const fetchResource = Object.keys(Deno.resources()).find((key) =>
Deno.resources()[parseInt(key)] === 'fetchResponse'
)
Deno.close(parseInt(fetchResource!))