react-native-fs
react-native-fs copied to clipboard
RNFS.downloadFile resolves without bytesWritten very often (RNFS v1.5.1)
react-native v0.33.0 react-native-fs v1.5.1
I make a habit of checking the size-on-disk of each file I download, because I've noticed that sometimes a download operation will produce a truncated file (less than 200 bytes, for a file in Amazon S3 that's 90k).
Lately, I've started relying on the resolution value of RNFS.downloadFile
, which is documented as containing jobId
, bytesWritten
, and statusCode
. Today I've discovered that bytesWritten
is often undefined, even though the file downloaded correctly and the statusCode
is 200
.
I used RNFS.stat
to verify the result of RNFS.downloadFile
. Even though bytesWritten
is undefined, stat
reports a size of 70k on disk (the correct size).
By "very often," I mean that bytesWritten
is incorrect 74 times out of 75. I've been building a caching module, and while putting it through its paces I've done nearly 1000 downloads of files around 90k.
Apologies if this is fixed in the newest version of RNFS.
@tomprogers were yo able to look into this issue further and come to a conclusion where we might have a bug?
@johanneslumpe Sorry, but no. I'm not an Obj-C dev. I can't trace or debug execution once it leaves the JS world. I see some code in Downloader.m that appears relevant, but I'm not equipped to figure out why it's not working.
i'm experiencing this too, byteswritten is undefined like 1 in 5
For what it's worth, I am getting this issue as well. But I seem to be getting it 100% for specific files.
I have been testing with some mp4 files and one jpeg file, and it consistently returns undefined
for bytesWritten for the jpeg file, but returns correct information for the mp4 files.
Maybe it has something to do with small files? E.g. there is some kind of race that causes bytesWritten to appear undefined if the file is really small and the download completes too quickly? (random thoughts)
I get this about once in 20 times. It is definitely happening for small files under 100KB in my case.
Also getting this error.
Is it okey to assume that if the DownloadResult
promise resolves then the file has been correctly downloaded? So instead of checking if bytesWritten
is equal to downloaded file size I do something like:
const downloadInfo = await fileManager.downloadFile({
fromUrl: asset.url,
toFile: `${AssetsManager.ASSETS_BASE_PATH}${asset.version}/${asset.name}`,
headers: getOpts.headers,
})
if (await downloadInfo.promise) {
// ASSET HAS BEEN DOWNLOADED!
}
I have tested this by removing internet connection and it worked (promise didn't resolve successfully). Am I missing a case where this may fail?
I have not tested this with the recent updates but I have had the promise resolve incorrectly. Below is a snippet of what works for me. I wrap the entire download call into a promise and resolve it only if the checks below pass.
// bytesWritten comes back undefined at times
// https://github.com/johanneslumpe/react-native-fs/issues/181
if (statusCode === 200 && (!bytesWritten || bytesWritten === contentLength)) {
// Success
}
It's still a fact that bad bytesWritten
is a bug that ought to be fixed.
Yes, the promise resolves IFF the download completes, but without bytesWritten
, it's impossible to know whether the data you saved to disk is the data you expected. Common example: make an incorrect "download" request to a URL that responds with an error page. Naive download code will unwittingly save the error HTML as a file on the device. The workaround is to make a second FS call to get the size of the new file from disk, but that's additional complexity that this module is supposed to eliminate.
Fix this bug.
I'm now seeing some very strange behavior with bytesWritten
all over the place ie. sometimes larger than contentLength
, sometimes smaller and obviously undefined at times.
I am facing this issue in iOS ....same code works fine on Android
I am using react-native version 0.63
react-native-fs version is 2.18.0
This is the response I am getting for iOS {"bytesWritten": 0, "jobId": 12, "statusCode": 200}
But there is not file written to the path I have given in toFile
argument
My download url is a .png
image from web
I am facing this issue in iOS ....same code works fine on Android I am using react-native version
0.63
react-native-fs version is2.18.0
This is the response I am getting for iOS{"bytesWritten": 0, "jobId": 12, "statusCode": 200}
But there is not file written to the path I have given in
toFile
argument My download url is a.png
image from web
Ok so I found out that issue in my case was that I was not saving image in default DocumentDirectoryPath
rather I was trying to save image in a folder one step deep in DocumentDirectoryPath
but that folder was never created
So I was giving ${RNFS.DocumentDirectoryPath}/MyAppName/products/image123.png
to toFile
parameter when in fact there was no folder name products
I am facing this issue in iOS ....same code works fine on Android I am using react-native version
0.63
react-native-fs version is2.18.0
This is the response I am getting for iOS{"bytesWritten": 0, "jobId": 12, "statusCode": 200}
But there is not file written to the path I have given intoFile
argument My download url is a.png
image from webOk so I found out that issue in my case was that I was not saving image in default
DocumentDirectoryPath
rather I was trying to save image in a folder one step deep inDocumentDirectoryPath
but that folder was never createdSo I was giving
${RNFS.DocumentDirectoryPath}/MyAppName/products/image123.png
totoFile
parameter when in fact there was no folder nameproducts
. that's why I first had to create folderproducts
insideRNFS.DocumentDirectoryPath}/MyAppName/
and then it worked fine