feathericons / feather

Simply beautiful open-source icons
https://feathericons.com
MIT License
24.91k stars 1.22k forks source link

Uncaught Exception if Icon Doesn't Exists. #1057

Open JamieSharpe opened 3 years ago

JamieSharpe commented 3 years ago

Prerequisites

Step to reproduce

Create a document with the following HTML:

<!DOCTYPE html>
<html lang="en">
  <title>Feather Icons Bug Report</title>
  <script src="https://unpkg.com/feather-icons"></script>
  <body>

    <!-- example icon -->
    <i data-feather="circle"></i>
    <i data-feather=""></i>
    <i data-feather="dot"></i>
    <i data-feather="circle"></i>

    <script>
      feather.replace()
    </script>
  </body>
</html>

And observe the browser JavaScript console/error log.

Expected behavior

It was expected that the erroneous element would be skipped, and not affect the remaining elements/icons that are to be inserted.

Actual behavior

Elements located within the DOM, up until an element with no, or an invalid, feather icon name will be correctly replaced with an icon. The problematic element will cause an uncaught exception, making further elements in the DOM not be replaced, even if they are correct.

Any message or error

Console log from FireFox v86.0:

Uncaught TypeError: r.default[o] is undefined
    default https://unpkg.com/feather-icons:12
    default https://unpkg.com/feather-icons:12
    default https://unpkg.com/feather-icons:12

Resources

An example of the error using the Feather template on Code Pen

2021-03-10 - 13-33-44-913 - firefox

moeenio commented 3 years ago

that's kinda expected

pathaksa commented 3 years ago

yes, mayb check if the icon exists before trying to do toSvg().

pathaksa commented 3 years ago

what you can do to avoid the exception is to check if the icon exists before calling feather.replace() if the icon doesn't exist, then remove the attribute [data-feather] from the element. after checking all, you can call feather.replace() safely.

                var elementsToReplace = document.querySelectorAll('[data-feather]');

                Array.from(elementsToReplace).forEach(function (element) {
                    let icon = element.getAttribute('data-feather');
                    if (typeof feather.icons[icon] === "undefined") {
                        element.removeAttribute('data-feather');
                    }
                });
mrsixx commented 6 months ago

Hi guys, how are you doing?

I was close to opening an issue about the same problem and found this thread.

In my case, I made a wrapper for my team to consume the icon rendering functionality and sometimes someone tries to consume a non-existent or wrong icon. It usually takes us a long time to figure out which one would be causing problems, since the exception breaks the pages and we have a lot of icons on them.

I propose throwing a warning in the console with the icon name and element when it doesn't exist. At least finding the problematic one will be easier: https://github.com/feathericons/feather/blob/81040345578c0b81bbe524c63484c0330278d7dc/src/replace.js#L34

will be

if (!icons[name])
    console.warn(`Feather: Icon named "${name}" not found. `, element);
 const svgString = icons[name].toSvg({ 

I could open a PR including this if you guys agree