#azure-cosmosdb
Вопрос:
Я пишу свой собственный метод доступа к cosmos db, который представляет собой оболочку для различных операций cosmos db, таких как создание, обновление, чтение документов.
напр.,
try
{
ItemResponse<T> response = await client.GetContainer(this.DatabaseId, this.ContainerId)
.UpsertItemAsync(document, new PartitionKey(document.PartitionKey)).ConfigureAwait(false);
}
catch (Exception ex)
{
logError(ex, ...);
throw ex;
}
что я замечаю, так это то, что иногда я получаю исключение SerializationException в блоке catch, трассировка стека:
System.Runtime.Serialization.SerializationException: Member 'HelpURL' was not found.
at System.Runtime.Serialization.SerializationInfo.GetElement(String name, Typeamp; foundType)
at System.Runtime.Serialization.SerializationInfo.GetString(String name)
at System.Exception..ctor(SerializationInfo info, StreamingContext context)
at lambda_method(Closure , Object[] )
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateISerializable(JsonReader reader, JsonISerializableContract contract, JsonProperty member, String id)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateISerializableItem(JToken token, Type type, JsonISerializableContract contract, JsonProperty member)
at Newtonsoft.Json.Serialization.JsonFormatterConverter.Convert(Object value, Type type)
at System.Runtime.Serialization.SerializationInfo.GetValue(String name, Type type)
at System.Exception..ctor(SerializationInfo info, StreamingContext context)
at lambda_method(Closure , Object[] )
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateISerializable(JsonReader reader, JsonISerializableContract contract, JsonProperty member, String id)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
поэтому я немного смущен тем, почему я получил такую ошибку при вызове cosmos db и где мне следует ее исследовать, как уже упоминалось, у меня много методов-оболочек, и до сих пор я замечаю, что эта ошибка обычно возникает в результате операции чтения, либо ReadItemAsync, либо операции обновления, которая требует чтения, а затем изменения.
Спасибо за любые предложения
Комментарии:
1. Как выглядит документ, который вы пытаетесь прочитать/обновить?
UpsertItemAsync
метод взят из пакета SDK Cosmos DB. Верно?
Ответ №1:
Сериализация происходит, когда необработанный JSON из службы в ответе преобразуется с помощью Newtonsoft.Json для <T>
модели или типа, с помощью которых вы вызываете метод.
Если у меня есть имя класса MyClass
с определенными свойствами и декораторами сериализации, если я это сделаю:
ItemResponse<MyClass> = await client.ReadItemAsync<MyClass>(....);
SDK примет необработанный ответ службы и попытается десериализовать его в экземпляр MyClass
. Ошибки Newtonsoft означают, что во время этого процесса возникла какая-то проблема, потенциально у необработанного JSON, хранящегося в службе, может возникнуть проблема с типом, к которому вы пытаетесь его сопоставить.
Обмен информацией о том, что у вас <T>
есть, может намекнуть на то, где может быть проблема, потенциально в каком-то свойстве, называемом HelpURL
? Это часть твоей <T>
жизни ?
Кроме того, какой SDK вы используете? Является ли это исключение полной трассировкой стека? Если да, то почему он не включает в себя вызов SDK? Вы уверены, что он исходит оттуда, а не с какого-то верхнего уровня, который также улавливает исключение, которое вы создаете, и пытается, например, сериализовать его для возврата в ответе веб-API?
Комментарии:
1. Я только что обновил sdk до версии 3.20.0 с версии 3.8.0, но проблема сохраняется. Я проверю производственные данные и проведу некоторый локальный тест, чтобы увидеть, смогу ли я воспроизвести ошибку локально, но я вижу, что это может быть как-то связано с необработанным ответом от десериализации cosmos db в объект (изначально я думал, что это связано с тем, что CosmosException не сериализуется). спасибо за ваше предложение.
2. Это также может быть последнее, их ключом является трассировка стека. Если трассировка стека указывает на вызов SDK, то это потенциально первый случай. Если трассировка стека указывает на точку, в которой вы могли бы возвращать исключение CosmosException вызывающему абоненту через ответ WebAPI, возможно, последнее.
Ответ №2:
Вы можете отдельно проверить операцию чтения/обновления/вставки, если эти вызовы работают нормально. Похоже, что какой-то вызов терпит неудачу в бэкэнде и выдает «HelpURL» в ответ, на что он пытается десериализоваться и терпит неудачу с этой ошибкой.
Комментарии:
1. да, это хорошее направление. Я проверю производственные данные и проведу некоторый локальный тест, чтобы увидеть, смогу ли я воспроизвести ошибку локально, но я вижу, что это как-то связано с необработанным ответом от десериализации cosmos db в объект. Спасибо