Skip to content
This repository has been archived by the owner on Mar 16, 2019. It is now read-only.

Crashes at first request using fetch() polyfill #288

Closed
GeoffreyPlitt opened this issue Mar 14, 2017 · 5 comments
Closed

Crashes at first request using fetch() polyfill #288

GeoffreyPlitt opened this issue Mar 14, 2017 · 5 comments

Comments

@GeoffreyPlitt
Copy link

GeoffreyPlitt commented Mar 14, 2017

I'm using RN=0.42 and the latest version of this lib, testing on iOS simulator.

We're using the "fetch polyfill" approach mentioned at https://github.com/wkh237/react-native-fetch-blob/wiki/Fetch-API#fetch-replacement.

As soon as we call fetch() with a HTTPs url, it crashes. From the logs, it appears to be a native exception, and I'm not quite sure what's wrong, but I imagine the authors of this lib will know.

Logs:

 *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFNumber length]: unrecognized selector sent to instance 0xb000000000000073'
	*** First throw call stack:
	(
		0   CoreFoundation                      0x0000000109517d4b __exceptionPreprocess + 171
		1   libobjc.A.dylib                     0x0000000107e5421e objc_exception_throw + 48
		2   CoreFoundation                      0x0000000109587f04 -[NSObject(NSObject) doesNotRecognizeSelector:] + 132
		3   CoreFoundation                      0x000000010949d005 ___forwarding___ + 1013
		4   CoreFoundation                      0x000000010949cb88 _CF_forwarding_prep_0 + 120
		5   CFNetwork                           0x0000000108d28731 _ZN15HTTPHeaderValue7isValidEPK10__CFString + 19
		6   CFNetwork                           0x0000000108d2868d _ZN11HTTPMessage25setHeaderFieldStringValueEPK10__CFStringS2_ + 41
		7   CFNetwork                           0x0000000108d30a45 _ZN11HTTPMessage23setMultipleHeaderFieldsEPK14__CFDictionary + 127
		8   CFNetwork                           0x0000000108da8248 CFURLRequestSetMultipleHTTPHeaderFields + 123
		9   Stardust                            0x00000001070ba164 __85+[RNFetchBlobReqBuilder buildOctetRequest:taskId:method:url:headers:body:onComplete:]_block_invoke + 4660
		10  libdispatch.dylib                   0x000000010db7e808 _dispatch_call_block_and_release + 12
		11  libdispatch.dylib                   0x000000010dba012e _dispatch_client_callout + 8
		12  libdispatch.dylib                   0x000000010db87bd2 _dispatch_root_queue_drain + 1008
		13  libdispatch.dylib                   0x000000010db87782 _dispatch_worker_thread3 + 113
		14  libsystem_pthread.dylib             0x000000010df464de _pthread_wqthread + 1129
		15  libsystem_pthread.dylib             0x000000010df44341 start_wqthread + 13
@GeoffreyPlitt
Copy link
Author

Does anyone understand the error?

@wkh237
Copy link
Owner

wkh237 commented Mar 19, 2017

@GeoffreyPlitt , is there a code snippet about how you use the fetch replacement? It'd be helpful to replicate the error.

@GeoffreyPlitt
Copy link
Author

GeoffreyPlitt commented Mar 19, 2017

Sure.

I define/override "fetch" as documented:

import RNFetchBlob from 'react-native-fetch-blob'
const Fetch = RNFetchBlob.polyfill.Fetch
// replace built-in fetch
const fetch = new Fetch({
    // enable this option so that the response data conversion handled automatically
    auto : true,
    // when receiving response data, the module will match its Content-Type header
    // with strings in this array. If it contains any one of string in this array, 
    // the response body will be considered as binary data and the data will be stored
    // in file system instead of in memory.
    // By default, it only store response data to file system when Content-Type 
    // contains string `application/octet`.
    binaryContentTypes : [
        'image/',
        'video/',
        'audio/',
        'foo/',
    ]
}).build()

Then I upload something with this kind of logic:

function upload_to_cloudinary(uri, type) {
    let timestamp = (Date.now() / 1000 | 0).toString()
    let hash_string = `${((type==='video') ? 'eager=sp_full_hd_wifi/m3u8&eager_async=true&' : '')}timestamp=${timestamp}${config.api_secret}`
    let signature = CryptoJS.SHA1(hash_string).toString()
    let upload_url = 'https://api.cloudinary.com/v1_1/' + cloudinary_config.cloud_name + `/${(type==='video') ? 'video' : 'image'}/upload`

    const formdata = new FormData()
    if(type==='video') {
      formdata.append('file', {uri: `file://${uri}`, type: 'video/mp4', name: 'upload.mp4'})
      formdata.append('eager', 'sp_full_hd_wifi/m3u8')
      formdata.append('eager_async', true)
    } else { // image
      formdata.append('file', {uri: `file://${uri}`, type: 'image/jpg', name: 'upload.jpg'})
    }
    formdata.append('timestamp', timestamp)
    formdata.append('api_key', cloudinary_config.api_key)
    formdata.append('signature', signature)

    return fetch(upload_url, {
      method: 'POST',
      body: formdata
    })
  }

@wkh237
Copy link
Owner

wkh237 commented Mar 26, 2017

@GeoffreyPlitt , I've tried to use your code to upload a file to Cloudinary, but I got a different error from the server.

{"error":{"message":"Invalid URL for upload"}}

I'll keep look into this issue (might take quite a long time) before I find solution I suggest you can try use RNFetchblob.fetch as described in #213 and see if that works 👍

@wkh237 wkh237 added the bug label Mar 26, 2017
wkh237 added a commit that referenced this issue Mar 28, 2017
Remove extra semi-column when Fetch Replacement parsing FormData #288

This is non-standard behavior which may cause server side incompatible.
@wkh237
Copy link
Owner

wkh237 commented Mar 28, 2017

I have noticed the form data generated by Fetch Replace has an extra semi-column which is non-standard also it causes Cloudinary server failed to parse the request body.

The fix already committed to branch issue-288, please try to upgrade your package and see if that fix the bug 👍

@wkh237 wkh237 closed this as completed Apr 14, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants