I am trying to upload files to AWS S3 bucket from my react native app but I get this error -> Possible Unhandled Promise Rejection (id: 0) Here is the code:
import { View, Text, StyleSheet, TouchableOpacity } from 'react-native'
import DocumentPicker from 'react-native-document-picker';
import { RNS3 } from 'react-native-aws3';
import Colors from '../constants/Colors';
const Upload = (props) => {
async function openDocumentFile() {
try {
const res = await DocumentPicker.pickSingle({
type: [DocumentPicker.types.allFiles],
});
console.log(
res.uri,
res.name,
res.type,
res.size
);
const file = {
uri: res.uri,
name: res.name,
type: res.type,
}
const options = {
keyPrefix: "uploads/",
bucket: '',
region: 'ap-south-1',
accessKey: '',
secretKey: '',
successActionStatus: 201
}
RNS3.put(file, options)
.then(response => {
if (response.status !== 201){
console.log(response.status);
throw new Error("Failed to upload image to S3");
}
console.log(response.body);
});
}
catch (err) {
if(DocumentPicker.isCancel(err)) {
console.log("user cancelled");
}
throw err;
}
}
return (
<View style={styles.view}>
<TouchableOpacity style={styles.button} onPress={openDocumentFile}>
<Text style={styles.text}>Upload Documents</Text>
</TouchableOpacity>
</View>
)
}
export default Upload;
const styles = StyleSheet.create({
view: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
button: {
justifyContent: 'center',
alignItems: 'center',
color: Colors.white,
padding: 10,
borderColor: Colors.primary,
borderWidth: 1,
},
text: {
color: Colors.primary,
}
})
Here is the output I get which shows that the file is correctly selected but there is error in the code to upload the file to AWS-S3:
LOG content://com.android.providers.downloads.documents/document/msf:31 helloWorld.jpeg image/jpeg 26150
LOG 400
WARN Possible Unhandled Promise Rejection (id: 0):
Error: Failed to upload image to S3
I checked other questions and answers, but I didn't find a solution. How can I solve this error?
CodePudding user response:
You're surrounding the problematic code with try
/catch
, which is good - but then you're re-throwing the error:
catch (err) {
if(DocumentPicker.isCancel(err)) {
console.log("user cancelled");
}
throw err;
}
which will result in an unhandled rejection unless there's another try
/catch
or .catch
around that.
Only throw if there's something higher up on the call stack that can handle it. In this case, there isn't - openDocumentFile
should handle everything itself - so don't re-throw in case of there's a problem.
catch (err) {
if(DocumentPicker.isCancel(err)) {
console.log("user cancelled");
}
}
You also need to properly await
the call to RNS3.put
- right now, it's not being waited for, so it's not connected with the try
/catch
. This:
RNS3.put(file, options)
.then(response => {
if (response.status !== 201){
console.log(response.status);
throw new Error("Failed to upload image to S3");
}
console.log(response.body);
});
should be
const response = await RNS3.put(file, options)
if (response.status !== 201){
console.log(response.status);
throw new Error("Failed to upload image to S3");
}
console.log(response.body);
Generally, don't mix await
and .then
unless you understand Promises completely and know what you're doing - otherwise, to avoid confusing yourself, I'd recommend using only one or the other in a particular segment of code. Either await
(and try
/catch
), or use .then
, but not both in the same section of asynchronous logic.