How to catch system.xml.xmlexception

1

I published a small free App for Windows Phone 8 Smartphones (to get to know C# - so I am a beginner in programming). A lot of my users seem pretty happy with the functionality but some of them seem to keep getting random crashes (for example in Canada: http://www.windowsphone.com/en-ca/store/app/picture-of-the-day/fc977a34-c09d-4c70-8a7b-66b6f09ab7f0) I never experienced such crashes on my test devices and tried to get rid of them by adding more try-catch statements - but without success.

The crash report states the following:

Frame Image Function Offset        
0 system_xml_ni System.Xml.XmlTextReaderImpl.Throw 0x00000036    
1 system_xml_ni System.Xml.XmlTextReaderImpl.ParseDocumentContent 0x00000438    
2 system_xml_ni System.Xml.XmlTextReaderImpl.Read 0x00000036    
3 system_xml_linq_ni System.Xml.Linq.XDeclaration..ctor 0x00000072    
4 system_xml_linq_ni System.Xml.Linq.XDocument.Load 0x0000010a    
5 system_xml_linq_ni System.Xml.Linq.XDocument.Load 0x00000042    
6 system_xml_linq_ni System.Xml.Linq.XDocument.Load 0x00000006    
7 phoneapp1_ni PhoneApp1.MainPage+__c__DisplayClassb._doLoadURL_b__6 0x00000040    
8 system_net_ni System.Net.WebClient.OnOpenReadCompleted 0x00000010    
9 system_net_ni System.Net.WebClient.OpenReadOperationCompleted 0x00000034`

The actual code that I think is responsible:

try 
{
    WebClient client = new WebClient();
    client.OpenReadAsync(new Uri(Url, UriKind.Absolute));
    client.OpenReadCompleted += (sender, e) =>
    {
        if (e.Error != null)
        {
            return;
        }
        else
        {
            System.Xml.Linq.XDocument xmlDoc = XDocument.Load(e.Result);
            IEnumerable<string> strTestURL = from node in xmlDoc.Descendants("url") select node.Value;
            IEnumerable<string> strTestDescription = from node in xmlDoc.Descendants("copyright") select node.Value;
            IEnumerable<string> strTestDate = from node in xmlDoc.Descendants("enddate") select node.Value;
            string strURL = "http://www.bing.com" + strTestURL.First();
            strURL = strURL.Replace("1366x768", "800x480");
            Global.URL1 = strURL;
            Global.URLs[i] = strURL;
            Global.Descriptions[i] = strTestDescription.First();
            Uri Uri = new Uri(Global.URLs[i], UriKind.Absolute);
            Imageallgemein.Source = new BitmapImage(Uri);
            Imageallgemein.Tap += new EventHandler<System.Windows.Input.GestureEventArgs>(onImageTap);
            Imageallgemein.Hold += new EventHandler<System.Windows.Input.GestureEventArgs>(onImageTap);
            Description.Text = Global.Descriptions[i];
            string Year = strTestDate.First().Substring(0, 4);
            string Month = strTestDate.First().Substring(4, 2);
            string Day = strTestDate.First().Substring(6, 2);
            Date.Text = Day + "." + Month + "." + Year;
        }
    };
}
catch
{
    MessageBox.Show(AppResources.Abort, AppResources.msgBoxUrlLoadError, MessageBoxButton.OK);
}

try-catch seems to have no effect and I hope someone can solve this for me.

c#
.net
visual-studio
windows-phone-8
asked on Stack Overflow Jul 3, 2014 by Daniel M • edited Jul 3, 2014 by Liam

2 Answers

3

There must be some problem with the XML provided by e.Result. Details about this might be in the XmlException message but you only included part of the stack trace.

You will have to figure out what the problem is in the first place and you will probably have to add some logging of what happens BEFORE you call XDocument.Load if you are unable to reproduce the problem on your own system.

You can also add an exception handler but that does not fix the problem but makes your app more robust and allows it to provide a slightly better user interface if something unexpected happens. What you have done is adding an exception handler around the calls to the WebClient methods but you are not catching exceptions thrown by the handler for client.OpenReadCompleted. This is an asynchronous callback that will execute on a threadpool thread, and any uncaught exceptions thrown by this thread will terminate your app.

You need to handle the exception with code like this:

client.OpenReadCompleted += (sender, e) =>
{
    try
    {
        if (e.Error != null)
        {
            return;
        }
        else
            ....
    }
    catch (Exception ex)
    {
        .... log and report the exception to allow the app to continue
    }
 }

And if you decide to add logging to your app it will be very useful to you if you log the entire text returned by ex.ToString(). This will give you a good textual description of the problem including inner exceptions and full stack traces.

answered on Stack Overflow Jul 3, 2014 by Martin Liversage • edited Jul 3, 2014 by Martin Liversage
2

Normally is good practice to do catch(Exception), in your case catch(system.xml.XmlException). However put a try-catch inside your else block because this is an asynchronous event and if occurs some exception inside that exception will be not catched:

try 
{
    WebClient client = new WebClient();
    client.OpenReadAsync(new Uri(Url, UriKind.Absolute));
    client.OpenReadCompleted += (sender, e) =>
    {
        if (e.Error != null)
        {
            return;
        }
        else
        {
           try
           {
              System.Xml.Linq.XDocument xmlDoc = XDocument.Load(e.Result);
              IEnumerable<string> strTestURL = from node in xmlDoc.Descendants("url") select node.Value;
              IEnumerable<string> strTestDescription = from node in xmlDoc.Descendants("copyright") select node.Value;
              IEnumerable<string> strTestDate = from node in xmlDoc.Descendants("enddate") select node.Value;
              string strURL = "http://www.bing.com" + strTestURL.First();
              strURL = strURL.Replace("1366x768", "800x480");
              Global.URL1 = strURL;
              Global.URLs[i] = strURL;
              Global.Descriptions[i] = strTestDescription.First();
              Uri Uri = new Uri(Global.URLs[i], UriKind.Absolute);
              Imageallgemein.Source = new BitmapImage(Uri);
              Imageallgemein.Tap += new EventHandler<System.Windows.Input.GestureEventArgs>(onImageTap);
              Imageallgemein.Hold += new EventHandler<System.Windows.Input.GestureEventArgs>(onImageTap);
              Description.Text = Global.Descriptions[i];
              string Year = strTestDate.First().Substring(0, 4);
              string Month = strTestDate.First().Substring(4, 2);
              string Day = strTestDate.First().Substring(6, 2);
              Date.Text = Day + "." + Month + "." + Year;
           }
           catch (XmlException)
           {
                MessageBox.Show(AppResources.Abort, AppResources.msgBoxUrlLoadError, MessageBoxButton.OK);
           }
        }
    };
}
catch (Exception)
{
    MessageBox.Show(AppResources.Abort, AppResources.msgBoxUrlLoadError, MessageBoxButton.OK);
}
answered on Stack Overflow Jul 3, 2014 by Ninita

User contributions licensed under CC BY-SA 3.0