Understanding Image and Media Failed Errors

October 17, 2008
No Comments.

Silverlight Logo
In meeting with a client (Schoolmaster.nl who is building a cool LOB app), we came across the problem of one of their components was throwing Image Failed Javascript errors. Handling them in the App.UnhandledException event didn’t help because the errors were surfaced outside the plug-in, directly to Javascript.  Immediately I use the VisualTreeHelper to walk the entire XAML tree (including nested templates) to just add an event handler on to every ImageFailed events to try and suppress these errors.

public Page()
{
  InitializeComponent();

  Loaded += (s, e) =>
    {
      // Call Recursive method to wire all Image tags
      WireImageFailed(this);
    };
}

void WireImageFailed(DependencyObject source)
{

  for (int x = 0; x < VisualTreeHelper.GetChildrenCount(source); ++x)
  {
    DependencyObject child = VisualTreeHelper.GetChild(source, x);
    if (child is Image)
    {
      ((Image)child).ImageFailed += (s,e)=>
        {
          // NOOP
        };
    }
    WireImageFailed(child);
  }

}

In case you’re not familiar with this class, it helps you walk through the entire render tree at runtime (including inside controls and control templates). This means I could look for all the Image objects and handle the event to suppress the error. This worked but it felt hacky and doesn’t work for them as they are building a lot of dynamic XAML.

After digging further, I found out that for compatibility with Silverlight 1.0, they are actually thrown at the Plug-in level so if you want to suppress them, just handle the OnError on the plugin. You can do this no matter how you are hosting the plugin:

<!-- ASP.NET Silverlight Control -->
<asp:Silverlight ID="Xaml1" 
                 runat="server" 
                 Source="~/ClientBin/BadImageTest.xap"
                 MinimumVersion="2.0.31005.0" 
                 Width="100%" 
                 Height="100%" 
                 OnPluginError="SLPluginError" />

<!-- OBJECT Tag -->
<object data="data:application/x-silverlight-2," 
        type="application/x-silverlight-2" 
        width="100%" 
        height="100%">
<param name="source" 
       value="ClientBin/BadImageTest.xap"/>
<param name="minRuntimeVersion" 
       value="2.0.31005.0" />
	<param name="onerror" 
       value="SLPluginError" />
</object>

By handling the plugin error, we can either do something about it or just ignore the image/media errors:

function SLPluginError(sender, args) {
  // NOOP
}

Its not elegant, but if you want to stop those annoying script errors from the plug-in, this is the way. At least until I get Microsoft to agree that this isn’t a valid way to handle it.