joltup / rn-fetch-blob

A project committed to making file access and data transfer easier, efficient for React Native developers.
MIT License
2.81k stars 770 forks source link

Class Cast exception #490

Open learnyst opened 4 years ago

learnyst commented 4 years ago

rnFetchBlob is crashing with the below exception. We have got this exception in bugsnag

java.lang.ClassCastException okhttp3.internal.http.RealResponseBody cannot be cast to com.RNFetchBlob.Response.RNFetchBlobFileResp RNFetchBlobReq.java:544 com.RNFetchBlob.RNFetchBlobReq.done RNFetchBlobReq.java:67 com.RNFetchBlob.RNFetchBlobReq.access$100 RNFetchBlobReq.java:445 com.RNFetchBlob.RNFetchBlobReq$3.onResponse RealCall.java:174 okhttp3.RealCall$AsyncCall.execute NamedRunnable.java:32 okhttp3.internal.NamedRunnable.run ThreadPoolExecutor.java:1113 java.util.concurrent.ThreadPoolExecutor.runWorker ThreadPoolExecutor.java:588 java.util.concurrent.ThreadPoolExecutor$Worker.run Thread.java:818 java.lang.Thread.run

z384647062 commented 4 years ago

Change RNFetchBlob.fs.dirs.MusicDir to RNFetchBlob.fs.dirs.DocumentDir in option path of RNFetchBlob.config helps me solve the problem

oleksandr-dziuban commented 4 years ago

Change RNFetchBlob.fs.dirs.MusicDir to RNFetchBlob.fs.dirs.DocumentDir in option path of RNFetchBlob.config helps me solve the problem

@z384647062 I have same issue, but don't use any RNFetchBlob.fs.dirs.MusicDir in app.

I use RNFetchBlob.fs.dirs.DocumentDir everywhere. Inеeresting that this error is only throws on non-clean Android. On Native Android (simulator or device) everything is OK. On Xiaomi, for example I see this error in MiUI

oleksandr-dziuban commented 4 years ago

Question to maintainers, Is it possible to review this issue please?

oleksandr-dziuban commented 4 years ago

@Traviskn Hello, I have checked this issues in 0.10.16 and it is not reproducible! Only the latest few versions throw this error for Android

oleksandr-dziuban commented 4 years ago

Any ideas guys?

Sumit-Chakole commented 4 years ago

Change RNFetchBlob.fs.dirs.MusicDir to RNFetchBlob.fs.dirs.DocumentDir in option path of RNFetchBlob.config helps me solve the problem

This worked in my case too :)

brianinator commented 4 years ago

Relates to recent PR #530 that is going to catch it and return back.

olcayertas commented 4 years ago

I am getting the same error on Mac OS X with Android simulator (API 29 Google Play):

let dir = Platform.OS === "ios" ? 
    RNFetchBlob.fs.dirs.DocumentDir : 
    RNFetchBlob.fs.dirs.DownloadDir;
console.log("Download location: " + dir);
let headers = { Authorization: "Bearer " + token };
let options = { fileCache: true, path : dir + '/file' };
RNFetchBlob.config(options).fetch("GET", url, headers)

Error:

java.lang.ClassCastException: okhttp3.internal.http.RealResponseBody
cannot be cast to com.RNFetchBlob.Response.RNFetchBlobFileResp
    at com.RNFetchBlob.RNFetchBlobReq.done(RNFetchBlobReq.java:594)
    at com.RNFetchBlob.RNFetchBlobReq.access$100(RNFetchBlobReq.java:72)
    at com.RNFetchBlob.RNFetchBlobReq$3.onResponse(RNFetchBlobReq.java:493)
    at okhttp3.RealCall$AsyncCall.execute(RealCall.java:206)
    at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
    at java.lang.Thread.run(Thread.java:919)

Version: 0.12.0 React: 0.61.5

nobady90 commented 4 years ago

same error in Xiaomi with android 9 and MIUI Global 11.3.4. in practice it seems that it does not resolve the gallery and therefore does not open the downloaded file with: RNFetchBlob.android.actionViewIntent (res.path (), item.mimeType);

instead everything works normally for example with pdf ... any help?

hadare1 commented 4 years ago

I have the same issue on Pixel 3 and, where do I need to make this change?

Change RNFetchBlob.fs.dirs.MusicDir to RNFetchBlob.fs.dirs.DocumentDir in option path of RNFetchBlob.config helps me solve the problem

This worked in my case too :)

funkyfourier commented 4 years ago

I am having this issue too. If I catch the exception, like in PR #530, then it will just fail silently and not download and save the file.

I am trying to download lots of files at once. They are for the most part slippy map tiles, in other words tiny png files. I slice the list of files in portions, so I do for example 20 at a time with Promise.all. Then I will get maybe 3-4 ClassCastExceptions for about 800 files.

Noticeably, the ClassCastException is not thrown when I only do Promise.all with one promise at a time. If I do two or more, the exception almost certainly will be thrown during those 800 files.

So, to be clear, I have an array of promises, about 800 of them, like this:

const fetchFile = (fileMeta) => {
        return new Promise((resolve, reject) => {
            fetchBlobTask = RNFetchBlob.config({
                path: fileMeta.filename,
                fileCache: true,
            }).fetch(
                'GET', encodeURI(fileMeta.url)
            );
            fetchBlobTask.then((result) => {
                resolve(result);
            }).catch((error) => {
                reject(error);
            });
        });
}

I then do Promise.all on (for example) 20 of those at a time. On iOS this works without a hitch. If I do only one at a time, it works on both platforms, but is painfully slow.

This happens on the emulator, on a OnePlus 6 and on a Sony XZ1.

It is also worth mentioning that the previous version of the app, which was built with Cordova, also had a similar issue on Android.

brianinator commented 4 years ago

Although downgrading to 0.10.16 made this issue go away, I decided to stay on 0.12.0 and switched to use Android download manager. The config I used:

config.addAndroidDownloads = {
  useDownloadManager: true,
  notification: true,
  mediaScannable: false,
  path: /path/to/file
};
oleksandr-dziuban commented 4 years ago

@Traviskn Hello, any ideas how to fix this issue? Possibly this PR breaks Android https://github.com/joltup/rn-fetch-blob/pull/530/files

Can we revert it and publish new npm package?

oleksandr-dziuban commented 4 years ago

Is this library still maintained? Looks like no...

Desintegrator commented 4 years ago

same ussue ((( help wanted Im don't use MusicDir in app

oleksandr-dziuban commented 4 years ago

@Traviskn Is it possible to revert PR related to this issue? We are blocked currently in out project with this issue

punksta commented 4 years ago

I am having the same issue in production app.

ahetesumspurtree commented 4 years ago

Any Update on this issue??? @Traviskn

nguyenhoanglam commented 4 years ago

I think the reason this error occurred is related to Android 10's file access policy. So I temporaryly fixed it by add android:requestLegacyExternalStorage="true" attribute to the application tag in AndroidManifest.xml file, like this:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.android.example">
       ...
    <application
        android:name="com.android.example.MainApplication"
        android:allowBackup="false"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:requestLegacyExternalStorage="true"
        android:theme="@style/AppTheme">

        ...
    </application>

</manifest>
nes123 commented 4 years ago

@nguyenhoanglam it does not work in my case, and i get the error also for android 9

Muratoter commented 4 years ago

@nguyenhoanglam Worked on Android 10, thanks.

Yarkhan commented 3 years ago

I was getting this error too in some Android devices. Some of the users of my app have denied the app permission to manage files, so when trying to downloading something the app would just crash. Checking the permissions before downloading have fixed this issue for me

Edit: While this fixed the issue for the majority of my users, there are some cases where the problem persists, even when the permissions are correctly set.

I will try to contact the user and send him a custom build using expo filesystem.

timxyz commented 3 years ago

Commenting here even though I can see PR #530 has been merged. I think that PR suppresses the crash but does not address the underlying cause, which is the custom OkHttp interceptor that is installed in RNFetchBlobReq.

This interceptor is responsible for wrapping the response body in an instance of RNFetchBlobDefaultResp. However I've noticed a crash can very occasionally occur like so:

  1. An initial request is made that fails with an exception. (e.g. SocketTimeoutException)
  2. The HTTP interceptor catches the exception. It has then been written to attempt the request again.
  3. If this request then succeeds, then the raw OkHttp response is returned to the caller. The interceptor does not wrap the response body as it is supposed to.
  4. The caller is expecting a response with a wrapped body and so crashes.

I have been able to reliably replicate the issue by programatically causing SocketTimeoutException to occur. I am then able to fix by modifying the code to propagate this exception, instead of making a second request. This causes RNFB to properly report a failure back to the RN code. An alternative fix would be to make sure the response from the second request is wrapped, but personally I don't think the interceptor should be implementing this kind of retry logic.

zhirzh commented 3 years ago

This issue exists because the exported dirs constant is populated using getExternalStoragePublicDirectory() which is deprecated in android 10

https://github.com/joltup/rn-fetch-blob/blob/9110ef295c42139407607f425ac2d46a5866e872/android/src/main/java/com/RNFetchBlob/RNFetchBlobFS.java#L250-L262

ebrahimmfadae commented 3 years ago

I also had this problem in Android 8.1.0 Nexus 5X. Attribute android:requestLegacyExternalStorage="true" didn't fix it but downgrading to 0.10.16 solved the issue. thanks @oleksandr-dziuban

tastyqbit commented 3 years ago

If you install from the master branch using npm install --save git+https://github.com/joltup/rn-fetch-blob.git it has been fixed

darron1217 commented 3 years ago

I solved it by following @nguyenhoanglam 's answer for android above 10, and requesting permission for android above 6. Here's my solution.

Android >= 10

add android:requestLegacyExternalStorage="true" on AndroidManifest.xml

Android >= 6

request permission before fetch

const requestExternalStoragePermissions = async () => {
  const read = await PermissionsAndroid.request(
    PermissionsAndroid.PERMISSIONS.READ_EXTERNAL_STORAGE,
  );
  const write = await PermissionsAndroid.request(
    PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE,
  );
  return (
    read === PermissionsAndroid.RESULTS.GRANTED &&
    write === PermissionsAndroid.RESULTS.GRANTED
  );
};
srbulovicdusan commented 2 years ago

I solved this problem by modifying rn-fetch-blob and saving those changes permanently using patch-package.

goldqwert commented 1 year ago

This lib not maintained. I used react-native-blob-util properly maintained. It's helped me to fix issues with Class Cast exception.