Skip to content

App crashes when uploading blob with fetch API #21851

@adam-hari

Description

@adam-hari

I found two instances where an issue was logged describing the same behaviour.
#20895
#21076

This issue is present in the latest React Native release (0.57.3)

Environment

React Native Environment Info:
System:
OS: macOS High Sierra 10.13.6
CPU: x64 Intel(R) Core(TM) i7-4960HQ CPU @ 2.60GHz
Memory: 1.00 GB / 16.00 GB
Shell: 3.2.57 - /bin/bash
Binaries:
Node: 9.5.0 - /usr/local/bin/node
Yarn: 1.7.0 - /usr/local/bin/yarn
npm: 6.1.0 - /usr/local/bin/npm
Watchman: 4.9.4 - /usr/local/bin/watchman
SDKs:
iOS SDK:
Platforms: iOS 11.4, macOS 10.13, tvOS 11.4, watchOS 4.3
Android SDK:
Build Tools: 26.0.3, 27.0.3, 28.0.1
API Levels: 23, 24, 25, 26, 27, 28
IDEs:
Android Studio: 3.1 AI-173.4819257
Xcode: 9.4.1/9F2000 - /usr/bin/xcodebuild
npmPackages:
react: 16.6.0-alpha.8af6728 => 16.6.0-alpha.8af6728
react-native: 0.57.3 => 0.57.3
npmGlobalPackages:
react-native-cli: 2.0.1
react-native-git-upgrade: 0.2.7
react-native-init: 0.6.7

Description

I am using the fetch API to upload a locally stored media file to a remote URI. With react-native@0.55.2 the upload will succeed or execute the catch block on fail. With react-native@0.57.3 Android will propagate the 'TypeError: Network Request Failed' to the catch block whereas iOS will intermittently not reach the catch block and will instead crash with the following exception:

ExceptionsManager.js:84 Exception '*** -[__NSPlaceholderDictionary initWithObjects:forKeys:count:]: attempt to insert nil object from objects[0]' was thrown while invoking sendRequest on target Networking with params (
        {
        data =         {
            blob =             {
                blobId = "3f45dd94-fec9-49e7-a4a9-91aa04bba12f";
                lastModified = 1539883597603;
                offset = 0;
                size = 1232959;
                type = "";
            };
            trackingName = unknown;
        };
        headers =         {
            "access-control-allow-origin" = "*";
        };
        incrementalUpdates = 0;
        method = PUT;
        responseType = text;
        timeout = 0;
        url = "https://d1na8u9bbyf6pn.cloudfront.net/twt-uat1/MUS2014123113584242167/69093975526/105000000204082.jpeg?Expires=1539883894&Signature=ONFNJ1XTY3FOLUIMDnrcpR7~Awuobkwx~P5Ab~4hYx5bnVf5fSKwAzbobWZNnYrmzVXHGiyUmVEfRSvuZtseaMJfx6y1Bs9oI5ewuLRf-r0zMn25gFsN228FQ3IBaki3BsXJXQ-d~yVfhlkA6rIxQ1bHxnJ0VOgxEr6UU9g8gny2NIHwQTppJwFQYyAOtY1yBQ7KtlWp-WcasQVcCZn0H7tG59a7rpBCFUcfaFozQS0Dduizyl972vuHBY6V6o2KiCTWRrTNnXvFMLTfzVYb8UXl9USbwHP2nGvnqAfYhYIlm4KeYcJU4VZC66iWypcOPrpfJkdokHmgXltkbJJHbA__&Key-Pair-Id=APKAJER34WYXWHOJ2NZQ";
        withCredentials = 0;
    },
    7285
)
callstack: (
	0   CoreFoundation                      0x00000001a7e2ff10 <redacted> + 252
	1   libobjc.A.dylib                     0x00000001a6ffda40 objc_exception_throw + 56
	2   CoreFoundation                      0x00000001a7da585c _CFArgv + 0
	3   CoreFoundation                      0x00000001a7d2beb0 <redacted> + 352
	4   CoreFoundation                      0x00000001a7d1c9f4 <redacted> + 64
	5   uploadErrorTest                     0x000000010255f838 -[RCTBlobManager handleNetworkingRequest:] + 664
	6   uploadErrorTest                     0x00000001027c041c -[RCTNetworking processDataForHTTPQuery:callback:] + 1436
	7   uploadErrorTest                     0x00000001027bf1c8 -[RCTNetworking buildRequest:completionBlock:] + 3108
	8   uploadErrorTest                     0x00000001027c57f8 -[RCTNetworking sendRequest:responseSender:] + 232
	9   CoreFoundation                      0x00000001a7e37660 <redacted> + 144
	10  CoreFoundation                      0x00000001a7d13980 <redacted> + 292
	11  CoreFoundation                      0x00000001a7d14564 <redacted> + 60
	12  uploadErrorTest                     0x00000001025f8ff4 -[RCTModuleMethod invokeWithBridge:module:arguments:] + 2064
	13  uploadErrorTest                     0x00000001026a828c _ZN8facebook5reactL11invokeInnerEP9RCTBridgeP13RCTModuleDatajRKN5folly7dynamicE + 664
	14  uploadErrorTest                     0x00000001026a7e1c _ZZN8facebook5react15RCTNativeModule6invokeEjON5folly7dynamicEiENK3$_0clEv + 132
	15  uploadErrorTest                     0x00000001026a7d8c ___ZN8facebook5react15RCTNativeModule6invokeEjON5folly7dynamicEi_block_invoke + 28
	16  libdispatch.dylib                   0x00000001a78676c8 <redacted> + 24
	17  libdispatch.dylib                   0x00000001a7868484 <redacted> + 16
	18  libdispatch.dylib                   0x00000001a780fc18 <redacted> + 592
	19  libdispatch.dylib                   0x00000001a7810760 <redacted> + 432
	20  libdispatch.dylib                   0x00000001a7818f00 <redacted> + 600
	21  libsystem_pthread.dylib             0x00000001a7a4a0f0 _pthread_wqthread + 312
	22  libsystem_pthread.dylib             0x00000001a7a4cd00 start_wqthread + 4
)

Reproducible Demo

import * as React from 'react';
import { Image, Text, TouchableOpacity, ScrollView, StyleSheet } from 'react-native';

export default class App extends React.Component {
	constructor(props) {
		super(props);

		this.state = {
			text: 'Press me',
			base64Image:
				'data:image/gif;base64,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',
			url: "https://d1na8u9bbyf6pn.cloudfront.net/twt-uat1/MUS2014123113584242167/69093975526/105000000204082.jpeg?Expires=1539883894&Signature=ONFNJ1XTY3FOLUIMDnrcpR7~Awuobkwx~P5Ab~4hYx5bnVf5fSKwAzbobWZNnYrmzVXHGiyUmVEfRSvuZtseaMJfx6y1Bs9oI5ewuLRf-r0zMn25gFsN228FQ3IBaki3BsXJXQ-d~yVfhlkA6rIxQ1bHxnJ0VOgxEr6UU9g8gny2NIHwQTppJwFQYyAOtY1yBQ7KtlWp-WcasQVcCZn0H7tG59a7rpBCFUcfaFozQS0Dduizyl972vuHBY6V6o2KiCTWRrTNnXvFMLTfzVYb8UXl9USbwHP2nGvnqAfYhYIlm4KeYcJU4VZC66iWypcOPrpfJkdokHmgXltkbJJHbA__&Key-Pair-Id=APKAJER34WYXWHOJ2NZQ"
		};
	}

	onPress = () => {
		this.setState({ text: 'Uploading' });

		this.uploadMedia()
			.then((text) => this.setState({text}))
			.catch((text) => this.setState({text}))
	};

	uploadMedia = async () => {
		return new Promise((resolve, reject) => {
			fetch(this.state.base64Image)
				.then((media) => media.blob())
				.then((mediaBlob) => {
					fetch(this.state.url, {
						method: 'PUT',
						headers: {
							'Access-Control-Allow-Origin': '*'
						},
						body: mediaBlob
					})
						.then(res => resolve(JSON.stringify(res)))
						.catch(err => reject(JSON.stringify(err)))
				})
				.catch(err => reject(JSON.stringify(err)))
		})
	};

	render() {
		return (
			<ScrollView contentContainerStyle={styles.container}>
				<TouchableOpacity onPress={this.onPress}>
					<Text style={styles.paragraph}>{this.state.text}</Text>
					<Image
						source={{ uri: this.state.base64Image }}
						style={{
							width: 100,
							height: 100,
						}}
					/>
				</TouchableOpacity>
			</ScrollView>
		);
	}
}

const styles = StyleSheet.create({
	container: {
		flex: 1,
		alignItems:'center',
		justifyContent:'center',
	},
	paragraph: {
	},
});

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions