mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-05-13 12:26:45 +08:00
Android: Add error description to Image onError callback (#22737)
Summary: fixes #19073 Changelog: ---------- [Android] [Fixed] - Add error description to Image onError callback Pull Request resolved: https://github.com/facebook/react-native/pull/22737 Differential Revision: D13676224 Pulled By: hramos fbshipit-source-id: 0dea7e97ae6517b8980ad02827f19d22cd3ef933
This commit is contained in:
committed by
Facebook Github Bot
parent
527fc9d192
commit
7795a672d3
@@ -6,6 +6,8 @@
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<!-- needed for screenshot tests -->
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<!-- needed for image onError tests -->
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
|
||||
<application
|
||||
android:hardwareAccelerated="false">
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<!-- needed for screenshot tests -->
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<!-- needed for image onError tests -->
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
|
||||
<application
|
||||
android:hardwareAccelerated="false">
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.react.tests;
|
||||
|
||||
import android.view.View;
|
||||
import com.facebook.react.testing.ReactAppInstrumentationTestCase;
|
||||
import com.facebook.react.testing.ReactInstanceSpecForTest;
|
||||
import com.facebook.react.testing.StringRecordingModule;
|
||||
|
||||
/**
|
||||
* Simple test case to check that onError does not get called with undefined
|
||||
*/
|
||||
public class ImageErrorTestCase extends ReactAppInstrumentationTestCase {
|
||||
|
||||
private StringRecordingModule mStringRecordingModule;
|
||||
|
||||
@Override
|
||||
protected String getReactApplicationKeyUnderTest() {
|
||||
return "ImageErrorTestApp";
|
||||
}
|
||||
|
||||
public void testErrorHasCause() throws Exception {
|
||||
assertNotNull(getViewByTestId("image-1"));
|
||||
assertNotNull(getViewByTestId("image-2"));
|
||||
assertNotNull(getViewByTestId("image-3"));
|
||||
|
||||
Thread.sleep(3000);
|
||||
|
||||
assertEquals(3, mStringRecordingModule.getCalls().size());
|
||||
assertEquals("Got error: Unsupported uri scheme! Uri is: ", mStringRecordingModule.getCalls().get(0));
|
||||
assertEquals("Got error: /does/not/exist: open failed: ENOENT (No such file or directory)", mStringRecordingModule.getCalls().get(1));
|
||||
assertEquals("Got error: Unexpected HTTP code Response{protocol=http/1.1, code=404, message=Not Found, url=https://typo_error_facebook.github.io/react/logo-og.png}", mStringRecordingModule.getCalls().get(2));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ReactInstanceSpecForTest createReactInstanceSpecForTest() {
|
||||
mStringRecordingModule = new StringRecordingModule();
|
||||
return super.createReactInstanceSpecForTest()
|
||||
.addNativeModule(mStringRecordingModule);
|
||||
}
|
||||
}
|
||||
58
ReactAndroid/src/androidTest/js/ImageErrorTestApp.js
Normal file
58
ReactAndroid/src/androidTest/js/ImageErrorTestApp.js
Normal file
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const React = require('React');
|
||||
const Image = require('Image');
|
||||
const StyleSheet = require('StyleSheet');
|
||||
const View = require('View');
|
||||
|
||||
const RecordingModule = require('NativeModules').Recording;
|
||||
|
||||
class ImageErrorTestApp extends React.Component {
|
||||
onError = e => {
|
||||
RecordingModule.record('Got error: ' + e.nativeEvent.error);
|
||||
};
|
||||
|
||||
render() {
|
||||
// For some reason image-2 needs explicit height. Without it onError is not triggered.
|
||||
return (
|
||||
<View>
|
||||
<Image
|
||||
testID="image-1"
|
||||
source={{uri: '/does/not/exist'}}
|
||||
onError={this.onError}
|
||||
/>
|
||||
<Image
|
||||
testID="image-2"
|
||||
source={{uri: 'file:///does/not/exist'}}
|
||||
style={styles.image}
|
||||
onError={this.onError}
|
||||
/>
|
||||
<Image
|
||||
testID="image-3"
|
||||
source={{
|
||||
uri: 'https://TYPO_ERROR_facebook.github.io/react/logo-og.png',
|
||||
}}
|
||||
onError={this.onError}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
image: {
|
||||
height: 50,
|
||||
width: 50,
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = ImageErrorTestApp;
|
||||
@@ -58,6 +58,10 @@ const apps = [
|
||||
appKey: 'ImageOverlayColorTestApp',
|
||||
component: () => require('ImageOverlayColorTestApp'),
|
||||
},
|
||||
{
|
||||
appKey: 'ImageErrorTestApp',
|
||||
component: () => require('ImageErrorTestApp'),
|
||||
},
|
||||
{
|
||||
appKey: 'InitialPropsTestApp',
|
||||
component: () => require('InitialPropsTestApp'),
|
||||
|
||||
@@ -33,13 +33,18 @@ public class ImageLoadEvent extends Event<ImageLoadEvent> {
|
||||
private final @Nullable String mImageUri;
|
||||
private final int mWidth;
|
||||
private final int mHeight;
|
||||
private final @Nullable String mImageError;
|
||||
|
||||
public ImageLoadEvent(int viewId, @ImageEventType int eventType) {
|
||||
this(viewId, eventType, null);
|
||||
}
|
||||
|
||||
public ImageLoadEvent(int viewId, @ImageEventType int eventType, boolean error, String message) {
|
||||
this(viewId, eventType, null, 0, 0, message);
|
||||
}
|
||||
|
||||
public ImageLoadEvent(int viewId, @ImageEventType int eventType, String imageUri) {
|
||||
this(viewId, eventType, imageUri, 0, 0);
|
||||
this(viewId, eventType, imageUri, 0, 0, null);
|
||||
}
|
||||
|
||||
public ImageLoadEvent(
|
||||
@@ -48,11 +53,22 @@ public class ImageLoadEvent extends Event<ImageLoadEvent> {
|
||||
@Nullable String imageUri,
|
||||
int width,
|
||||
int height) {
|
||||
this(viewId, eventType, imageUri, width, height, null);
|
||||
}
|
||||
|
||||
public ImageLoadEvent(
|
||||
int viewId,
|
||||
@ImageEventType int eventType,
|
||||
@Nullable String imageUri,
|
||||
int width,
|
||||
int height,
|
||||
@Nullable String message) {
|
||||
super(viewId);
|
||||
mEventType = eventType;
|
||||
mImageUri = imageUri;
|
||||
mWidth = width;
|
||||
mHeight = height;
|
||||
mImageError = message;
|
||||
}
|
||||
|
||||
public static String eventNameForType(@ImageEventType int eventType) {
|
||||
@@ -88,7 +104,7 @@ public class ImageLoadEvent extends Event<ImageLoadEvent> {
|
||||
public void dispatch(RCTEventEmitter rctEventEmitter) {
|
||||
WritableMap eventData = null;
|
||||
|
||||
if (mImageUri != null || mEventType == ON_LOAD) {
|
||||
if (mImageUri != null || (mEventType == ON_LOAD || mEventType == ON_ERROR)) {
|
||||
eventData = Arguments.createMap();
|
||||
|
||||
if (mImageUri != null) {
|
||||
@@ -103,6 +119,8 @@ public class ImageLoadEvent extends Event<ImageLoadEvent> {
|
||||
source.putString("url", mImageUri);
|
||||
}
|
||||
eventData.putMap("source", source);
|
||||
} else if (mEventType == ON_ERROR) {
|
||||
eventData.putString("error", mImageError);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -262,9 +262,8 @@ public class ReactImageView extends GenericDraweeView {
|
||||
@Override
|
||||
public void onFailure(String id, Throwable throwable) {
|
||||
mEventDispatcher.dispatchEvent(
|
||||
new ImageLoadEvent(getId(), ImageLoadEvent.ON_ERROR));
|
||||
mEventDispatcher.dispatchEvent(
|
||||
new ImageLoadEvent(getId(), ImageLoadEvent.ON_LOAD_END));
|
||||
new ImageLoadEvent(getId(), ImageLoadEvent.ON_ERROR,
|
||||
true, throwable.getMessage()));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user