react-native-blob-util icon indicating copy to clipboard operation
react-native-blob-util copied to clipboard

Incorrect data in callback [email protected]

Open szujak opened this issue 7 months ago • 4 comments

Hello,

After upgrading to 0.22.1 I noticed that there is an issue with returning data from ReactNativeBlobUtil.df on windows.

I'm calling this method const availableDiskSpace = await ReactNativeBlobUtil.fs.df(); but instead of information about storage the error is thrown with message {"code":"EUNSPECIFIED"}

After checking the df method code I noticed that on windows the storage info is populated in err argument

function df(): Promise<{ free: number, total: number }> {
    return new Promise((resolve, reject) => {
        ReactNativeBlobUtil.df((err, stat) => {
            console.log(err, stat) // the err argument contains [{"free": 123, "total": 1234}] and stat is undefined
            if (err)
                reject(addCode('EUNSPECIFIED', new Error(err)));
            else
                resolve(stat);
        });
    });
}

Calling the same method on android works fine - err is null and stat contains storage info

szujak avatar May 28 '25 07:05 szujak

Also the data format looks different on Android and Windows

Android (object): {"external_free": "51120422912", "external_total": "52655943680", "internal_free": "51120422912", "internal_total": "52655943680"}

Windows (array with object): [{"free": 337609101312, "total": 1023285473280}]

szujak avatar May 28 '25 07:05 szujak

For now I adjusted winrt::fire_and_forget ReactNativeBlobUtil::df function to

winrt::fire_and_forget ReactNativeBlobUtil::df(
    std::function<void(::React::JSValue, ::React::JSValue)> callback) noexcept
{ 
        try
        {
            auto localFolder = winrt::Windows::Storage::ApplicationData::Current().LocalFolder();
            auto properties{ co_await localFolder.Properties().RetrievePropertiesAsync({L"System.FreeSpace", L"System.Capacity"}) };

            winrt::Microsoft::ReactNative::JSValueObject result;
            result["free"] = winrt::unbox_value<uint64_t>(properties.Lookup(L"System.FreeSpace"));
            result["total"] = winrt::unbox_value<uint64_t>(properties.Lookup(L"System.Capacity"));

            callback(nullptr, ::React::JSValueObject(std::move(result)));
        }
        catch (...)
        {
            winrt::Microsoft::ReactNative::JSValueObject error;
            error["error"] = "Failed to get storage usage.";

            callback(::React::JSValueObject(std::move(error)), nullptr);
        }
}

szujak avatar May 28 '25 07:05 szujak

Yes, this was generated as per the codegen Spec file which had std::function<void(::React::JSValueArray)> callback. @RonRadtke can confirm which one we should follow? JS to C++ via turbomodules https://github.com/RonRadtke/react-native-blob-util/blob/1533f64669a3c9f0f06e3a41ac93d5c294382a33/codegenSpecs/NativeBlobUtils.js#L64

anupriya13 avatar May 28 '25 13:05 anupriya13

I would say the codegen ist wrong here. It should be a plain object, no need for wrapping it in an array. But should check that iOS is doing the same then. Sadly enough we can't use the exact same keys for Android / win / iOS

RonRadtke avatar May 29 '25 21:05 RonRadtke