Skip to content

Commit 7cf8891

Browse files
committed
show error on failure to load image
1 parent 7345454 commit 7cf8891

File tree

2 files changed

+53
-2
lines changed

2 files changed

+53
-2
lines changed

src/Annotator/index.story.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -647,3 +647,23 @@ storiesOf("Annotator", module)
647647
</HotKeys>
648648
)
649649
})
650+
.add("CORs Error (Pixel Segmentation)", () => (
651+
<Annotator
652+
onExit={actionAddon("onExit")}
653+
middlewares={[
654+
(store) => (next) => (action) => {
655+
actionAddon(action.type)(action)
656+
return next(action)
657+
},
658+
]}
659+
labelImages
660+
fullImageSegmentationMode
661+
regionClsList={["Alpha", "Beta", "Charlie", "Delta"]}
662+
images={[
663+
{
664+
src: "https://placebear.com/200/300",
665+
name: "Frame 0036",
666+
},
667+
]}
668+
/>
669+
))

src/VideoOrImageCanvasBackground/index.js

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// @flow weak
22

3-
import React, { useRef, useEffect, useMemo } from "react"
3+
import React, { useRef, useEffect, useMemo, useState } from "react"
44
import { styled } from "@material-ui/core/styles"
55
import useEventCallback from "use-event-callback"
66
import { useSettings } from "../SettingsProvider"
@@ -15,6 +15,20 @@ const StyledImage = styled("img")({
1515
position: "absolute",
1616
})
1717

18+
const Error = styled("div")({
19+
zIndex: 0,
20+
position: "absolute",
21+
left: 0,
22+
right: 0,
23+
bottom: 0,
24+
top: 0,
25+
backgroundColor: "rgba(255,0,0,0.2)",
26+
color: "#ff0000",
27+
fontWeight: "bold",
28+
whiteSpace: "pre-wrap",
29+
padding: 50,
30+
})
31+
1832
export default ({
1933
imagePosition,
2034
mouseEvents,
@@ -30,6 +44,7 @@ export default ({
3044
const settings = useSettings()
3145
const videoRef = useRef()
3246
const imageRef = useRef()
47+
const [error, setError] = useState()
3348

3449
useEffect(() => {
3550
if (!videoPlaying && videoRef.current) {
@@ -93,6 +108,18 @@ export default ({
93108
imageElm,
94109
})
95110
})
111+
const onImageError = useEventCallback((event) => {
112+
console.log(event.toString(), event, event.stack)
113+
setError(
114+
`Could not load image\n\nMake sure your image works by visiting ${
115+
imageSrc || videoSrc
116+
} in a web browser. If that URL works, the server hosting the URL may be not allowing you to access the image from your current domain. Adjust server settings to enable the image to be viewed.${
117+
!useCrossOrigin
118+
? ""
119+
: `\n\nYour image may be blocked because it's not being sent with CORs headers. To do pixel segmentation, browser web security requires CORs headers in order for the algorithm to read the pixel data from the image. CORs headers are easy to add if you're using an S3 bucket or own the server hosting your images.`
120+
}\n\n If you need a hand, reach out to the community at universaldatatool.slack.com`
121+
)
122+
})
96123

97124
const stylePosition = useMemo(() => {
98125
let width = imagePosition.bottomRight.x - imagePosition.topLeft.x
@@ -111,7 +138,10 @@ export default ({
111138
imagePosition.bottomRight.y,
112139
])
113140

114-
if (!videoSrc && !imageSrc) return "No imageSrc or videoSrc provided"
141+
if (!videoSrc && !imageSrc)
142+
return <Error>No imageSrc or videoSrc provided</Error>
143+
144+
if (error) return <Error>{error}</Error>
115145

116146
return imageSrc && videoTime === undefined ? (
117147
<StyledImage
@@ -120,6 +150,7 @@ export default ({
120150
ref={imageRef}
121151
style={stylePosition}
122152
onLoad={onImageLoaded}
153+
onError={onImageError}
123154
crossOrigin={useCrossOrigin ? "anonymous" : undefined}
124155
/>
125156
) : (

0 commit comments

Comments
 (0)