Azure Cosmos DB - 检查项目是否不存在而不向 Application Insights 抛出错误

Azure Cosmos DB - check if item not exists without throwing error to Application Insights

我在 ASP.NET Core 3.1 中构建了一个简单的玩家跟踪 API 应用程序,它使用 Azure Cosmos DB 作为其后端。

创建新播放器条目的API 首先检查 Cosmos DB 中是否已存在给定分区键下具有相同 ID 的条目:

try
{
    ItemResponse<Player> response = await this._playerContainer.ReadItemAsync<Player>(playerid, new PartitionKey(partitionkey));
    return Conflict();
}
catch (CosmosException ex) when (ex.StatusCode == System.Net.HttpStatusCode.NotFound)
{
    // There is some more logic happening here so I cannot directly just call CreateItemAsync()... and return the Conflict response that this might return.
    ItemResponse<GameResult> response = await this._gameResultContainer.CreateItemAsync<GameResult>(gameresult, new PartitionKey(gameresult.PlayerId));
    // ...        
    return Accepted();
}

只有当 return 什么都没有时,我才会继续将创建请求放入后端工作队列。否则我 return 给 API 调用者一个 409 冲突。

实际插入发生在异步后端工作器中。但是我想直接 return 给 API 调用者,如果他的插入成功的话。

到目前为止一切正常。我遇到的问题如下:当我使用 Azure Application Insights SDK 时,任何未找到现有项目的调用(这应该是这里的正常情况)都会自动在 AppInsights 中创建错误 - 即使我发现了我的代码中的异常。这显然使我的日志记录混乱不堪。

知道如何摆脱它或通常如何更改 API 以获得更好的行为吗?

问题出在 Cosmos DB .NET SDK 端。如果找不到文档,它会抛出异常。他们无法真正改变这种行为,因为客户依赖它。 GitHub Issue

建议的解决方法是使用较低级别 Stream API。 这样您就可以处理 404 行为。

像这样:

    using (ResponseMessage responseMessage = await container.ReadItemStreamAsync(
        partitionKey: new PartitionKey(partitionkey),
        id: playerid))
    {
        if (responseMessage.StatusCode == System.Net.HttpStatusCode.NotFound)
        {
            ...
            return Accepted();
        }

        if (responseMessage.IsSuccessStatusCode)
        {
            return Conflict();
        }
    }

sample code in the repo for doing custom deserialization