2
votes

In a Silverlight 4 app I am calling a function on an included control (DataGrid), and this function sometimes throws a spurious exception of type MS.Internal.WrappedException. Since this exception is meaningless, I need to swallow it. Unfortunately, the exception is declared internal class WrappedException : Exception in System.Windows.dll, so I can't name it in a catch block.

The question is, what is the safest way to detect this exception and ignore it? The two options I've come up with are:

  1. Look for the original exception: ex.InnerException is InvalidOperationException
  2. Look for the name: ex.GetType().FullName == "MS.Internal.WrappedException"

Is one way better than the other? Is there another option I didn't think of?

Here's my function showing the different options:

    private void SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        var selectedAlarm = alarmList.SelectedItem as Alarm;
        if (selectedAlarm != null)
        {
            dataGrid.SelectedItem = selectedAlarm.Source;
            try
            {
                dataGrid.ScrollIntoView(dataGrid.SelectedItem, null);
            }
            // catch (MS.Internal.WrappedException ex) doesn't compile
            catch (Exception ex)
            {
                if (ex.InnerException is InvalidOperationException) // 1
                if (ex.GetType().FullName == "MS.Internal.WrappedException") // 2
                {
                    // ignore exception
                }
                else
                    throw;
            }
        }
    }

For those who are interested, here's the StackTrace:

   at MS.Internal.XcpImports.CheckHResult(UInt32 hr)
   at MS.Internal.XcpImports.UIElement_Measure(UIElement element, Size availableSize)
   at System.Windows.UIElement.Measure(Size availableSize)
   at System.Windows.Controls.DataGrid.InsertDisplayedElement(Int32 slot, UIElement element, Boolean wasNewlyAdded, Boolean updateSlotInformation)
   at System.Windows.Controls.DataGrid.InsertDisplayedElement(Int32 slot, Boolean updateSlotInformation)
   at System.Windows.Controls.DataGrid.GetExactSlotElementHeight(Int32 slot)
   at System.Windows.Controls.DataGrid.ScrollSlotIntoView(Int32 slot, Boolean scrolledHorizontally)
   at System.Windows.Controls.DataGrid.ScrollSlotIntoView(Int32 columnIndex, Int32 slot, Boolean forCurrentCellChange, Boolean forceHorizontalScroll)
   at System.Windows.Controls.DataGrid.ScrollIntoView(Object item, DataGridColumn column)
   at DtDemo.Home.alarmList_SelectionChanged(Object sender, SelectionChangedEventArgs e)

and here's InnerException.StackTrace:

   at System.Windows.Controls.DataGridRow.get_ActualDetailsVisibility()
   at System.Windows.Controls.DataGridRow.OnApplyTemplate()
   at System.Windows.FrameworkElement.OnApplyTemplate(IntPtr nativeTarget)
3

3 Answers

6
votes

This is intentional, so you don't try to catch this exception. It is a serious one, it is not meaningless, do not ignore it. Fix the real problem. I can't help you diagnose the reason without a stack trace.

2
votes

I would prefer the test for ex.InnerException is InvalidOperationException, and also possibly checking some of the properties of the InnerException.

It's a subjective judgement, though. It somehow feels less 'hacky', and maybe less likely to break in a future version. Do you think Microsoft is more likely to change the namespace or class name of their internal wrapper class, or do something like just throw the InvalidOperationException without wrapping it?

Of course, ideally you could stop the exception from being thrown in the first place. I'm sure you've already exhausted this route.

0
votes

Never mind. I should actually read the entire post.

I'd vote for using reflection (option #2).

I would argue that this is bug that should be reported to Microsoft: the public interface of an assembly shouldn't be throwing internal or private exceptions to its consumer.