如何在 Python Azure 函数中捕获 Azure Table 抛出的异常

How to catch an Exception thrown by Azure Table in Python Azure Function

问题

我有一个用 Python 3.8 编写的 Azure Function HTTP 触发函数。此函数接收传入的 HTTP 请求并将实体写入 Azure Table。如果传入请求尝试创建重复条目,Azure Table 会向 Azure 函数 运行 抛出 EntityAlreadyExists 错误。我想捕获这个异常并相应地处理它。

我可以在 python 中使用 Azure 函数中的 try/except 块捕获此异常吗?如果是这样,如何?如果不是,你知道为什么吗?

我尝试过的东西

None 成功捕获了 Azure Table 为重复输入尝试抛出的异常。

链接

抛出错误

这是我试图从我的 HTTP 触发的 Azure 函数中捕获的错误

Executed 'Functions.myTable' (Failed, Id=xxx-xxx-xxx-xxx, Duration=1256ms)
System.Private.CoreLib: Exception while executing function: Functions.myTable. Microsoft.Azure.WebJobs.Host: Error while handling parameter _binder after function returned:. Microsoft.Azure.WebJobs.Extensions.Storage: The specified entity already exists.
RequestId:xxx-xxx-xxx-xxx
Time:2020-09-30T13:16:00.9339049Z (HTTP status code 409: EntityAlreadyExists. The specified entity already exists.
RequestId:xxx-xxx-xxx-xxx
Time:2020-09-30T13:16:00.9339049Z). Microsoft.WindowsAzure.Storage: The specified entity already exists.
RequestId:xxx-xxx-xxx-xxx
Time:2020-09-30T13:16:00.9339049Z.

--init--.py

下面是 Azure 函数的 py 文件的相关部分。问题围绕第 16-27 行中的 try/except 块(未显示行号)。

import logging
import json
import azure.functions as func

def main(req: func.HttpRequest, myTable: func.Out[str]) -> func.HttpResponse:

    body = req.get_json()

    data = { # Data to send to Azure Table
        "PartitionKey": body.get('var1'),
        "RowKey": body.get('var2'),
        "Property1" : body.get('var3'),
        "Property2" : body.get('var4')
    }

    try: # Try to send record to Azure Table

        myTable.set(json.dumps(data))

    except ValueError as err: # Respond with 409 if duplicate record

        logging.error(err)

        return func.HttpResponse(
            body=f'Record already exists.',
            status_code=409
        )

    else: # Otherwise, respond with 201 success

        return func.HttpResponse(
                body=f'Success.',
                status_code=201
            )

function.json

下面是 Azure 函数的触发器和绑定 json。

{
  "scriptFile": "__init__.py",
  "bindings": [
    {
      "authLevel": "function",
      "type": "httpTrigger",
      "direction": "in",
      "name": "req",
      "methods": [
        "post"
      ]
    },
    {
      "name": "myTable",
      "type": "table",
      "tableName": "myTable",
      "connection": "AzureWebJobsStorage",
      "direction": "out"
    },
    {
      "type": "http",
      "direction": "out",
      "name": "$return"
    }
  ]
}

如果您正在使用 python。 Python只能使用声明式绑定方式,不能使用命令式绑定方式,所以如果要使用绑定来实现,使用'try catch'是不可能的。

正确的做法是把逻辑放在函数的内容里,然后就可以用try catch了。

Azure Table Storage 在预览版中有一个新的 python 库,可通过 pip 安装。要安装,请使用以下 pip 命令

pip install azure-data-tables

在 Azure Functions 中,您可以使用 try/except 块来捕获由 Tables 响应引发的异常。从 Azure Functions 访问您的 Tables 帐户的推荐方法是通过启用 MSI 的 KeyVault 客户端检索您的凭据以验证您的 TableClient。尝试创建新 table 的示例函数如下所示:

import azure.functions as func

def main(req: func.HttpRequest) -> func.HttpResponse:
    logging.info('Python HTTP trigger function processed a request.')

    from azure.identity import ManagedIdentityCredential
    from azure.keyvault.secrets import SecretClient

    credential = ManagedIdentityCredential()
    client = SecretClient("https://tablesfunctions.vault.azure.net", credential)
    conn_str = client.get_secret("tables-connstr")

    from azure.data.tables import TableClient
    from azure.core.exceptions import ResourceExistsError

    table_client = TableClient.from_connection_string(conn_str, table_name="MyTableName")
    try:
        table_client.create_table()
    except ResourceExistsError:
        return func.HttpResponse("Table already exists")

(仅供参考,我为 Python 团队开发 Azure SDK。)