diff --git a/ReactWindows/ReactNative.Shared/Views/Image/ReactImageLoadEvent.cs b/ReactWindows/ReactNative.Shared/Views/Image/ReactImageLoadEvent.cs
index 21c82193875..cccbff5bc7b 100644
--- a/ReactWindows/ReactNative.Shared/Views/Image/ReactImageLoadEvent.cs
+++ b/ReactWindows/ReactNative.Shared/Views/Image/ReactImageLoadEvent.cs
@@ -25,10 +25,16 @@ public class ReactImageLoadEvent : Event
///
public const int OnLoadEnd = 3;
+ ///
+ /// The event identifier for image load error.
+ ///
+ public const int OnError = 4;
+
private readonly int _eventType;
private readonly string _imageUri;
private readonly int _width;
private readonly int _height;
+ private readonly string _error;
///
/// Instantiates a .
@@ -57,6 +63,18 @@ public ReactImageLoadEvent(int viewId, int eventType, string imageUri, int width
_height = height;
}
+ ///
+ /// Instantiates a .
+ ///
+ /// The view identifier.
+ /// The error string.
+ public ReactImageLoadEvent(int viewId, string error)
+ : base(viewId)
+ {
+ _eventType = OnError;
+ _error = error;
+ }
+
///
/// The name of the event.
///
@@ -72,6 +90,8 @@ public override string EventName
return "topLoad";
case OnLoadEnd:
return "topLoadEnd";
+ case OnError:
+ return "topError";
default:
throw new InvalidOperationException(
Invariant($"Invalid image event '{_eventType}'."));
@@ -135,7 +155,15 @@ public override void Dispatch(RCTEventEmitter eventEmitter)
}
}
+ if (_eventType == OnError)
+ {
+ eventData = new JObject()
+ {
+ { "error", _error }
+ };
+ }
+
eventEmitter.receiveEvent(ViewTag, EventName, eventData);
}
}
-}
\ No newline at end of file
+}
diff --git a/ReactWindows/ReactNative/Views/Image/ReactImageManager.cs b/ReactWindows/ReactNative/Views/Image/ReactImageManager.cs
index 394d2707a63..d12aa31482c 100644
--- a/ReactWindows/ReactNative/Views/Image/ReactImageManager.cs
+++ b/ReactWindows/ReactNative/Views/Image/ReactImageManager.cs
@@ -64,6 +64,13 @@ public override IReadOnlyDictionary ExportedCustomDirectEventTyp
{ "registrationName", "onLoadEnd" }
}
},
+ {
+ "topError",
+ new Dictionary
+ {
+ { "registrationName", "onError" }
+ }
+ },
};
}
}
@@ -234,7 +241,7 @@ public override void SetDimensions(Border view, Dimensions dimensions)
SetUriFromMultipleSources(view);
}
- private void OnImageFailed(Border view)
+ private void OnImageFailed(Border view, Exception e)
{
if (!view.HasTag())
{
@@ -242,13 +249,20 @@ private void OnImageFailed(Border view)
return;
}
- view.GetReactContext()
+ var eventDispatcher = view.GetReactContext()
.GetNativeModule()
- .EventDispatcher
- .DispatchEvent(
- new ReactImageLoadEvent(
- view.GetTag(),
- ReactImageLoadEvent.OnLoadEnd));
+ .EventDispatcher;
+
+ eventDispatcher.DispatchEvent(
+ new ReactImageLoadEvent(
+ view.GetTag(),
+ e.Message));
+
+ eventDispatcher.DispatchEvent(
+ new ReactImageLoadEvent(
+ view.GetTag(),
+ ReactImageLoadEvent.OnLoadEnd));
+
}
private void OnImageStatusUpdate(Border view, ImageLoadStatus status, ImageMetadata metadata)
@@ -290,9 +304,9 @@ private async void SetUriFromSingleSource(Border view, string source)
imageBrush.ImageSource = image;
OnImageStatusUpdate(view, ImageLoadStatus.OnLoadEnd, metadata);
}
- catch
+ catch (Exception e)
{
- OnImageFailed(view);
+ OnImageFailed(view, e);
}
}