首页 > 解决方案 > Azure Cosmos DB - 检查项目是否不存在而不向 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();
}

只有当这没有返回任何内容时,我才会继续将创建请求放入后端工作队列中。否则,我会向 API 调用者返回 409-Conflict。

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

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

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

标签: c#azureasp.net-coreazure-cosmosdbazure-application-insights

解决方案


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

建议的解决方法是使用较低级别的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();
        }
    }

repo 中有用于自定义反序列化的示例代码


推荐阅读