SharePoint CSOM не выдает ожидаемые исключения в ExecuteQuery - PullRequest
2 голосов
/ 16 июня 2020

По сути, то, что говорит заголовок, по какой-либо причине, когда я вызываю clientContext.ExecuteQuery(); и, например, в списке, в который входят данные, отсутствует столбец, я не получаю исключения, он на самом деле просто работает, как ожидалось, и у меня на go и выясните, что могло стать причиной отсутствия данных.

Я использую пакет NuGet Microsoft.SharePoint2016.CSOM версия 16.0.4690.1000

Приветствуются любые намеки или предложения, указывающие мне в правильном направлении. Вполне возможно, что я здесь немного тупой.

Вот полный блок кода, который я использую для обновления элементов списка:

public override object UpdateEntity(object entity)
{
    if (entity == null)
    {
        // if the definition is null throw argument null exception.
        throw new ArgumentNullException(nameof(SharePointDefinition));
    }

    // check for incorrect type being passed in that we can still handle
    if (entity is List<SharePointDefinition> definitions)
    {
        return UpdateEntities(definitions);
    }

    ExceptionHandlingScope exceptionScopeFetch = new ExceptionHandlingScope(clientContext);
    ExceptionHandlingScope exceptionScopeSubmit = new ExceptionHandlingScope(clientContext);

    // run single definition submit to SP.
    if (entity is SharePointDefinition definition)
    {
        // variables.
        IntegrationEventLog log = new IntegrationEventLog();
        EventInformation ei = new EventInformation();
        List list = null;
        ListItemCollection listItemCol = null;

        using (exceptionScopeFetch.StartScope())
        {
            using (exceptionScopeFetch.StartTry())
            {
                // get the required list
                list = clientContext.Web.Lists.GetByTitle(definition.ListName);

                // create query
                listItemCol = list.GetItems(CamlQuery.CreateAllItemsQuery());

                // set these items for retrieval.
                clientContext.Load(listItemCol);
            }

            using (exceptionScopeFetch.StartCatch())
            {
                // Assume that if there's an exception, it can only be 
                // because there is no list with the specified title, so report this back.
                if (exceptionScopeFetch.HasException)
                {
                    ei = new EventInformation()
                    {
                        LoggingEventType = LoggingEventType.DataSentFailure,
                        LoggingSeverity = LoggingSeverity.HighSeverity,
                        SerialisedMessage = JsonConvert.SerializeObject(definition),
                        ServiceMessage = $"Hit SharePoint exception handler during list and data pull: Message: {exceptionScopeFetch.ErrorMessage}",
                        StackTrace = exceptionScopeFetch.ServerStackTrace,
                        TimeGenerated = DateTime.Now,
                        TimeWritten = DateTime.Now,
                    };

                    log.EventLogEntryType = EventLogEntryType.Error;
                    log.EventID = LoggingSeverity.HighSeverity;
                    log.Message = JsonConvert.SerializeObject(ei);
                    AddToLog(log);
                }
            }

            using (exceptionScopeFetch.StartFinally())
            {
                //
            }
        }

        // get item instances first
        try
        {
            clientContext.ExecuteQuery();
        }
        catch (Exception genEx)
        {
            // return failure log.
            ei = new EventInformation()
            {
                LoggingEventType = LoggingEventType.DataSentFailure,
                LoggingSeverity = LoggingSeverity.HighSeverity,
                SerialisedMessage = JsonConvert.SerializeObject(definition),
                ServiceMessage = "Errored trying to get data from SharePoint list ready for update operation; see stacktrace for more information.",
                StackTrace = genEx.StackTrace,
                TimeGenerated = DateTime.Now,
                TimeWritten = DateTime.Now,
            };

            log.EventLogEntryType = EventLogEntryType.Error;
            log.EventID = LoggingSeverity.HighSeverity;
            log.Message = JsonConvert.SerializeObject(ei);
            AddToLog(log);

            return false;
        }

        // this is the column we want to overwrite.
        var comparisonColumn = definition.UpdateIdentifier ?? "";

        //List col to dict
        var listItems = listItemCol.Cast<ListItem>().ToList();

        // Now we know if we were able to retrieve existing data, perform submit.
        using (exceptionScopeSubmit.StartScope())
        {
            using (exceptionScopeSubmit.StartTry())
            {
                // loop through our rows
                foreach (var row in definition.RowData)
                {
                    int existingItemIndex = -1;
                    // see if the row exists already
                    if (!string.IsNullOrEmpty(comparisonColumn) && listItems.Count != 0)
                    {
                        existingItemIndex = listItems.FindIndex(x => x[comparisonColumn].ToString() == row[comparisonColumn]);
                    }

                    if (existingItemIndex != -1 && listItems.Count != 0)
                    {
                        // item exists - loop through our row columns
                        foreach (var keyValuePair in row)
                        {
                            // they key relates to a column, the Value to the rows colum Value.
                            listItems[existingItemIndex].ParseAndSetFieldValue(keyValuePair.Key, keyValuePair.Value);
                        }

                        // update this item
                        listItems[existingItemIndex].Update();
                    }
                    else
                    {
                        ListItemCreationInformation itemCreateInfo = new ListItemCreationInformation();
                        ListItem newItem = list.AddItem(itemCreateInfo);

                        // loop through our row columns
                        foreach (var keyValuePair in row)
                        {
                            // they key relates to a column, the Value to the rows colum Value.
                            newItem[keyValuePair.Key] = keyValuePair.Value;
                        }
                        newItem.Update();
                    }
                }
            }

            using (exceptionScopeSubmit.StartCatch())
            {
                // Assume that if there's an exception, it can only be 
                // because there is no list with the specified title, so report this back.
                if (exceptionScopeFetch.HasException)
                {
                    ei = new EventInformation()
                    {
                        LoggingEventType = LoggingEventType.DataSentFailure,
                        LoggingSeverity = LoggingSeverity.HighSeverity,
                        SerialisedMessage = JsonConvert.SerializeObject(definition),
                        ServiceMessage = $"Error at SharePoint exception handler during submit to list: Message: {exceptionScopeFetch.ErrorMessage}",
                        StackTrace = exceptionScopeFetch.ServerStackTrace,
                        TimeGenerated = DateTime.Now,
                        TimeWritten = DateTime.Now,
                    };

                    log.EventLogEntryType = EventLogEntryType.Error;
                    log.EventID = LoggingSeverity.HighSeverity;
                    log.Message = JsonConvert.SerializeObject(ei);
                    AddToLog(log);
                }
            }

            using (exceptionScopeSubmit.StartFinally())
            {
                //
            }
        }

        // try to execute submit.
        try
        {
            clientContext.ExecuteQuery();

            ei = new EventInformation()
            {
                LoggingEventType = LoggingEventType.DataSentSuccess,
                LoggingSeverity = LoggingSeverity.Information,
                SerialisedMessage = JsonConvert.SerializeObject(definition),
                ServiceMessage = "No exceptions were thrown from the Execution process.",
                StackTrace = "",
                TimeGenerated = DateTime.Now,
                TimeWritten = DateTime.Now,
            };

            log.EventLogEntryType = EventLogEntryType.Information;
            log.EventID = LoggingSeverity.Information;
            log.Message = JsonConvert.SerializeObject(ei);
        }
        catch (Exception genEx)
        {
            ei = new EventInformation()
            {
                LoggingEventType = LoggingEventType.DataSentFailure,
                LoggingSeverity = LoggingSeverity.HighSeverity,
                SerialisedMessage = JsonConvert.SerializeObject(definition),
                ServiceMessage = $"Data failed to be updated within SharePoint - {genEx.Message} - see stacktrace for more information.",
                StackTrace = genEx.StackTrace,
                TimeGenerated = DateTime.Now,
                TimeWritten = DateTime.Now,
            };

            log.EventLogEntryType = EventLogEntryType.Error;
            log.EventID = LoggingSeverity.HighSeverity;
            log.Message = JsonConvert.SerializeObject(ei);
            AddToLog(log);

            return false;
        }

        AddToLog(log);
        return true;
    }
    else
    {
        // If a different definition type is passed in throw an appropriate exception. 
        // This should be caught at runtime only.
        throw new TypeLoadException(nameof(SharePointDefinition));
    }
}

Ответы [ 2 ]

1 голос
/ 23 июня 2020

Я проверил опубликованный вами код и вижу, что вы обновляете список объектов, в вашем случае listItems , вместо ListItem в ListItemCollection , в вашем случае listItemCol . Чтобы быть более понятным, я считаю, что вы можете попробовать заменить listItems на listItemCol . Например, вместо:

listItems[existingItemIndex].ParseAndSetFieldValue(keyValuePair.Key, keyValuePair.Value);

используйте

listItemCol[existingItemIndex][keyValuePair.Key] = keyValuePair.Value;
0 голосов
/ 16 июля 2020

Итак, я ушел и перечитал много документации и просмотрел некоторые примеры, и мне стало интересно, почему обработчик исключений никогда не возвращает ошибки, хотя очевидно, что были проблемы с выполняемым запросом. Если вы посмотрите документацию Microsoft и их пример здесь , вы увидите, что они не показывают вам, как использовать компонент exceptionScopeSubmit.HasException объекта области исключения. Что привело к действительно глупому предположению с моей стороны. Оказывается, блок исключения работает на сервере SharePoint и должен использоваться для исправления проблем, которые вы могли вызвать во время ожидаемого исключения в вашем запросе.

Не только это, но и упаковка ExecuteQuery в try catch является избыточным при использовании области исключения, поскольку это означает, что метод больше не будет генерировать исключение. На самом деле вам нужно оценить exceptionScopeSubmit.HasException после выполнения, чтобы получить более подробную информацию об ошибках, обнаруженных при выполнении вашего запроса на стороне сервера SharePoint.

Итак, теперь я использую его, как показано ниже, и могу получить подробную информацию об ошибках, не прибегая к какой-то дурацкой отладке вручную, на поиск глупых проблем у меня уйдет несколько часов. Так что, если кто-то наткнется на это с теми же проблемами, я надеюсь, что это поможет.

ExceptionHandlingScope exceptionScopeFetch = new ExceptionHandlingScope(clientContext);

// variables.
IntegrationEventLog log = new IntegrationEventLog();
EventInformation ei = new EventInformation();
List list = null;
ListItemCollection listItemCol = null;

using (exceptionScopeFetch.StartScope())
{
    using (exceptionScopeFetch.StartTry())
    {
        // get the required list
        list = clientContext.Web.Lists.GetByTitle(definition.ListName);

        // create query
        listItemCol = list.GetItems(CamlQuery.CreateAllItemsQuery());

        // set these items for retrieval.
        clientContext.Load(listItemCol);
    }

    using (exceptionScopeFetch.StartCatch())
    {
        //
    }

    using (exceptionScopeFetch.StartFinally())
    {
        //
    }
}

// get item instances first
clientContext.ExecuteQuery();
    
if (exceptionScopeSubmit.HasException)
{
    ei = new EventInformation()
    {
        LoggingEventType = LoggingEventType.DataSentFailure,
        LoggingSeverity = LoggingSeverity.HighSeverity,
        SerialisedMessage = JsonConvert.SerializeObject(definition),
        ServiceMessage = $"Error at SharePoint exception handler during submit to list: Message: {exceptionScopeFetch.ErrorMessage}",
        StackTrace = exceptionScopeFetch.ServerStackTrace,
        TimeGenerated = DateTime.Now,
        TimeWritten = DateTime.Now,
    };

    log.EventLogEntryType = EventLogEntryType.Error;
    log.EventID = LoggingSeverity.HighSeverity;
    log.Message = JsonConvert.SerializeObject(ei);
    AddToLog(log);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...