简体   繁体   中英

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

Problem

I have an Azure Function HTTP triggered function written in Python 3.8. This function receives an incoming HTTP request and writes an entity to an Azure Table. If an incoming request tries to create a duplicate entry, Azure Table throws an EntityAlreadyExists error to the Azure Function runner. I would like to catch this exception and handle it accordingly.

Can I catch this exception in python using a try / except block from within the Azure Function? If so, how? If not, do you know why?

Things I have tried

  • try to run code, then except ValueError as err: to handle exception
  • try to run code, then except Exception as err: to handle exception
  • try to run code, then except EntityAlreadyExists as err: to handle exception

None of these were successful at catching the exception being thrown from Azure Table for a duplicate entry attempt.

Links

Error thrown

This is the error I am trying to catch from within my HTTP-triggered Azure Function

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

Below is relevant portions of the py file for the Azure function. The question surrounds the try / except block in Lines 16-27 (line numbers not shown).

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

Below are the triggers and bindings json for the Azure function.

{
  "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"
    }
  ]
}

If you are using python. Python can only use declarative binding mode, but not imperative binding mode, so if you want to use binding to achieve, it is impossible to use'try catch'.

The right way is put the logic in the content of the function and then you can use try catch.

Azure Table Storage has a new python library in preview release that is available for installation via pip. To install use the following pip command

pip install azure-data-tables

Within Azure Functions you can use a try / except block to catch exceptions thrown by a Tables response. The recommended way to access your Tables account from an Azure Functions is through an MSI enabled KeyVault client to retrieve your credential to authenticate your TableClient. An example function that tries to create a new table would look like:

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

(FYI I work on the Azure SDK for Python team.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM