简体   繁体   中英

build Try-Catch in IEnumerable when reading XML

I am hitting an exception in the XML when running this particular block of code. I have established a try-catch but VS2010 is saying "'WindowsFormsApplication1.Form1.GetDocumentsData(string)': not all code paths return a value". The exceptions range from null value to XML formatting exceptions. I just need to capture them and will log them into a file (that part of the code is not done yet).

C# code:

    private static IEnumerable<object[]> GetDocumentsData(string folderPath = @"filepath")
    {
        try
        {
            return Directory.GetFiles(folderPath, "*.xml")
               .Select(XDocument.Load)
               .SelectMany(file => file.Descendants().Where(e => e.Name.LocalName == "FilingLeadDocument").Concat(file.Descendants().Where(e => e.Name.LocalName == "FilingConnectedDocument")))
               .Select(documentNode =>
               {
                   var receivedDateNode = documentNode.Elements().FirstOrDefault(e => e.Name.LocalName == "DocumentReceivedDate");
                   var descriptionNode = documentNode.Elements().FirstOrDefault(e => e.Name.LocalName == "DocumentDescriptionText");
                   var metadataNode = documentNode.Elements().FirstOrDefault(e => e.Name.LocalName == "DocumentMetadata");
                   var registerActionNode = metadataNode.Elements().FirstOrDefault(e => e.Name.LocalName == "RegisterActionDescriptionText");

                   return new object[]
  {
       (string)documentNode.Parent.Parent.Elements().FirstOrDefault(e => e.Name.LocalName == "DocumentIdentification"),
       (DateTime?)receivedDateNode.Elements().FirstOrDefault(e => e.Name.LocalName == "DateTime"),
       descriptionNode != null ? descriptionNode.Value.Trim() : string.Empty,
       registerActionNode != null ? registerActionNode.Value.Trim() : string.Empty
  };
               }).ToArray();
        }
        catch (Exception e)
        { }
    }

To fix your actual compilation error, just return an empty IEnumerable in the event of an exception:

private static IEnumerable<object[]> GetDocumentsData(string folderPath = @"filepath")
{
    try
    {
        return Directory.GetFiles(folderPath, "*.xml")
           .Select(XDocument.Load)
           .SelectMany(file => file.Descendants().Where(e => e.Name.LocalName == "FilingLeadDocument").Concat(file.Descendants().Where(e => e.Name.LocalName == "FilingConnectedDocument")))
           .Select(documentNode =>
           {
               var receivedDateNode = documentNode.Elements().FirstOrDefault(e => e.Name.LocalName == "DocumentReceivedDate");
               var descriptionNode = documentNode.Elements().FirstOrDefault(e => e.Name.LocalName == "DocumentDescriptionText");
               var metadataNode = documentNode.Elements().FirstOrDefault(e => e.Name.LocalName == "DocumentMetadata");
               var registerActionNode = metadataNode.Elements().FirstOrDefault(e => e.Name.LocalName == "RegisterActionDescriptionText");

              return new object[]
              {
                   (string)documentNode.Parent.Parent.Elements().FirstOrDefault(e => e.Name.LocalName == "DocumentIdentification"),
                   (DateTime?)receivedDateNode.Elements().FirstOrDefault(e => e.Name.LocalName == "DateTime"),
                   descriptionNode != null ? descriptionNode.Value.Trim() : string.Empty,
                   registerActionNode != null ? registerActionNode.Value.Trim() : string.Empty
              };
           }).ToArray();
    }
    catch (Exception e)
    { 
        return Enumerable.Empty<object[]>();
    }
}

However, I'd question why you are "happy" with these errors -> exceptions are not to be ignored usually. If an exception happens here , what do you expect to happen further up the chain?

You get the error because there's no return statement in the catch block. This is necessary, because if there would be an exception thrown, what would the method have to return?
So, add return null; in the catch block, and when you use your method elsewhere in your project, check for null .

Your code don't return value in catch block. This is why your code cannot compile. You should decide what value you want to return from this method when exception was thrown. Or, may be, you should catch this exception in caller method, not here.

Since your method should return a value, it means that the Catch block is a block that should return something.
either IEnumerable<object[]> , null or you should throw an Exception and let someone else handle it. Since your catch block preventing the exception to be fly back, you should treat this block as it was outside of the try catch block

Edit - this is a different story
you will have to separate it into foreach, than inside the foreach do the try catch
if the catch will hit, it will write to log and continue to the next one.
(your code is impossible to read, I think you might want to break it down to blocks)

 private static IEnumerable<object[]> GetDocumentsData(string folderPath = @"filepath")
        {
            IList<object[]> collection = new List<object[]>();
            foreach (var file in Directory.GetFiles(folderPath, "*.xml"))
            {
                try
                {
                    /// do the proccecing here
                    collection.Add(/*your found elements*/);
                }

                catch(Exception e)
                {
                    log.Error("Cant get collection", e);

                }
            }
            return col;
        }

Another solution - please be careful I dont know your code and where the exception thrown

private static IEnumerable<object[]> GetDocumentsData(string folderPath = @"filepath")
        {

                return Directory.GetFiles(folderPath, "*.xml")
                   .Select(XDocument.Load)
                   .SelectMany(file => file.Descendants().Where(e => e.Name.LocalName == "FilingLeadDocument").Concat(file.Descendants().Where(e => e.Name.LocalName == "FilingConnectedDocument")))
                   .Select(documentNode =>
                   {
                       try
                       {
                           var receivedDateNode =
                               documentNode.Elements().FirstOrDefault(e => e.Name.LocalName == "DocumentReceivedDate");
                           var descriptionNode =
                               documentNode.Elements()
                                           .FirstOrDefault(e => e.Name.LocalName == "DocumentDescriptionText");
                           var metadataNode =
                               documentNode.Elements().FirstOrDefault(e => e.Name.LocalName == "DocumentMetadata");
                           var registerActionNode =
                               metadataNode.Elements()
                                           .FirstOrDefault(e => e.Name.LocalName == "RegisterActionDescriptionText");

                           return new object[]
                               {
                                   (string)
                                   documentNode.Parent.Parent.Elements()
                                               .FirstOrDefault(e => e.Name.LocalName == "DocumentIdentification"),
                                   (DateTime?)
                                   receivedDateNode.Elements().FirstOrDefault(e => e.Name.LocalName == "DateTime"),
                                   descriptionNode != null ? descriptionNode.Value.Trim() : string.Empty,
                                   registerActionNode != null ? registerActionNode.Value.Trim() : string.Empty
                               };
                       }
                       catch (Exception e)
                       {
                           //Log.error("");
                           return new object[] {};
                       }
                   }).ToArray();

        }

如果要处理循环中的错误并继续处理,还可以在IEnumerable方法内使用yield return处理每个结果,类似于此处的模式https://stackoverflow.com/a/32656320/1037948

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM