Azure / azure-functions-core-tools

Command line tools for Azure Functions
MIT License
1.29k stars 426 forks source link

CosmosDB error - Can't figure out which ctor to call. #3677

Open dfberry opened 3 months ago

dfberry commented 3 months ago

On Node.js/TS/pm v4 - I have a CosmosDB trigger for tableA, then I want to process each doc, and insert into table B. I'm using extraOutputs because it is more obvious to me. Is there anything wrong with it?

Incoming doc has blob storage URL of a JSON object with mulitple items, I want each item to be insert into a different table. So this function turns 1 doc in tableA into many docs in tableB. Is there a better way to do this?

import { app, InvocationContext, output } from "@azure/functions";
import { ProcessingDocument } from "../models";
import { getJsonFromBlob } from "../azure-blob-storage";

const sendToCosmosDb = output.cosmosDB({
    databaseName: 'github_history',
    containerName: 'issues',
    connection: 'AZURE_COSMOSDB_CONNECTION_STRING',
    createIfNotExists: false,
});

export async function listenToDatabase(documents: unknown[], context: InvocationContext): Promise<void> {

    try {

        context.log(`Cosmos DB function processed ${documents.length} documents`);

        for (const doc of documents) {

            const docToProcess = doc as ProcessingDocument;

            // filename like `20240511_my_daily_issues_and_prs_1.json`
            // which has a format of `YYYYMMDD_{name}_{numDays}.json`
            // regex to extract the date and name and number of days
            const regex = /^(\d{8})_(.+)_(\d+)\.json$/;
            const match = docToProcess.name.match(regex);

            // extract the date and name and number of days
            const date = match[1];
            const name = match[2];
            const numDays = parseInt(match[3]);

            // Read DB doc
            context.log(`Processing document with date ${date}, name ${name}, and numDays ${numDays}`);

            // Read blob
            const data = await getJsonFromBlob(docToProcess.url, process.env.AZURE_STORAGE_CONNECTION_STRING, context.log);

            // Get the inner docs to send to a different DB table
            const innerDocs = data?.results.items

            for (const innerDoc of innerDocs) {
                context.extraOutputs.set(sendToCosmosDb, {
                    type: name,
                    ...innerDoc
                });
            }
        }
    } catch (error) {
        context.log(`listenToDatabase - Error processing documents: ${error}`);

    }
}
app.cosmosDB('listen-to-database', {
    connectionStringSetting: 'AZURE_COSMOSDB_CONNECTION_STRING',
    databaseName: 'github_history',
    collectionName: 'data_processing',
    createLeaseCollectionIfNotExists: true,
    extraOutputs: [sendToCosmosDb],
    handler: listenToDatabase
});

Error is : [2024-05-12T22:05:01.897Z] The 'listen-to-database' function is in error: Unable to configure binding 'cosmosDBTrigger026ae58797' of type 'cosmosDBTrigger'. This may indicate invalid function.json properties. Can't figure out which ctor to call.

dfberry commented 3 months ago

Found this existing issue which is still open - https://github.com/Azure/Azure-Functions/issues/2447