Skip to content

App crashes when uploading blob with fetch API #21851

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: {
	},
});

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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