如何在Python Azure函数中捕获Azure表引发的异常

问题描述

问题

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

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

我尝试过的事情

  • try运行代码,然后except ValueError as err:处理异常
  • try运行代码,然后except Exception as err:处理异常
  • try运行代码,然后except EntityAlreadyExists as err:处理异常

这些都不成功捕获从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 表存储在预览版中有一个新的 Python 库,可通过 pip 安装。要安装使用以下 pip 命令

pip install azure-data-tables

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

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")

(仅供参考,我在 Azure SDK for Python 团队工作。)