Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug: img element not dispatching error events when trying to get a non-existent resource from the same origin #8271

Closed
charlie632 opened this issue Dec 28, 2022 · 6 comments
Labels
support Issues that aren't actually issues, and don't need a milestone

Comments

@charlie632
Copy link

Describe the bug

I have the following code in SvelteKit:

<img
  src={''}
  on:error={(e) => console.log('Error', e)}
/>

The on:error event callback is never called.

However, if I change the source to hello-there, and I refresh the page, I get the following error in the console:
GET http://localhost:5173/hello-there 404 (Not Found), but the callback is not called.

However, if I make a change and let the HMR reload the contents, the error callback is called!!

Additionally, if I change the src to another domain, for example, https://123thisshouldntexit.com/cdieo, the error callback is always called, no matter if it's a new page load or HRM.

I wonder if it's due to the svelte JS being loaded after the initial HTML is loaded, so all events are "lost" or "missed" by the runtime.

If that's the case, is there a way to know if an image didn't load? I usually use the error event, but I don't know if it's reliable with SvelteKit.

Reproduction

https://github.com/charlie632/sveltkit-bug-image-repro/blob/main/src/routes/%2Bpage.svelte

Just go to the default localhost and open the console.

Do a change, and when the HMR hits, the console should have all three logs.

Logs

No response

System Info

System:
    OS: macOS 13.1
    CPU: (10) arm64 Apple M1 Pro
    Memory: 567.53 MB / 32.00 GB
    Shell: 5.8.1 - /bin/zsh
  Binaries:
    Node: 18.5.0 - ~/.nvm/versions/node/v18.5.0/bin/node
    Yarn: 1.22.19 - ~/.nvm/versions/node/v18.5.0/bin/yarn
    npm: 8.12.1 - ~/.nvm/versions/node/v18.5.0/bin/npm
  Browsers:
    Chrome: 108.0.5359.124
    Chrome Canary: 109.0.5383.2
    Edge: 108.0.1462.54
    Firefox: 107.0.1
    Safari: 16.2
  npmPackages:
    @sveltejs/adapter-auto: ^1.0.0 => 1.0.0
    @sveltejs/kit: ^1.0.0 => 1.0.1
    svelte: ^3.54.0 => 3.55.0
    vite: ^4.0.0 => 4.0.3

Severity

serious, but I can work around it

Additional Information

No response

@Rich-Harris
Copy link
Member

Your diagnosis...

I wonder if it's due to the svelte JS being loaded after the initial HTML is loaded, so all events are "lost" or "missed" by the runtime.

...is correct. Unfortunately I'm not sure if there's a way to detect whether an image previously failed to load, which seems like a shocking omission on the part of the platform. I would love to be corrected here!

@Rich-Harris Rich-Harris added the support Issues that aren't actually issues, and don't need a milestone label Feb 1, 2023
@Conduitry
Copy link
Member

Yeah, that was my diagnosis as well when I looked at this issue back when it was opened, but apparently I never commented on it. It was similar to a previous issue about 'how can I find out when an image was loaded', where the answer was 'write an action that checks whether it's already loaded and attach an event handler if not' - but in this case, I recall not being able to find a 'did this image already fail to load' property on the DOM, which seemed bizarre.

@Conduitry
Copy link
Member

In terms of what to actually do about this, what I would try is an old-fashioned onerror attribute (something like onerror="this.__error = true") and then having an action that looks for that __error property you set, calls the callback if it's already set, and attaches an error event handler otherwise and calls your callback if that's called. It's definitely ugly. It might be more palatable if you wrap up this whole thing (the onerror attribute and the action) into a reusable component.

@Rich-Harris
Copy link
Member

You can also check if img.naturalWidth === 0 && img.naturalHeight === 0, which is true if the image failed to load, but is also true if the image is zero by zero pixels.

I'm going to close this as I don't think there's anything we could be doing differently here, this is just an unfortunate characteristic of the platform.

@Rich-Harris Rich-Harris closed this as not planned Won't fix, can't repro, duplicate, stale Feb 8, 2023
@charlie632
Copy link
Author

fair enough. thanks @Conduitry and @Rich-Harris for looking at it.

cheers

@ABSanthosh
Copy link

I found a strange concoction of workarounds to make onerror work on sveltekit.

{@html `<img src="${img}" alt="${name}" onerror="this.style.visibility = 'hidden'" />`}

Works for my use case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
support Issues that aren't actually issues, and don't need a milestone
Projects
None yet
Development

No branches or pull requests

4 participants