Search code examples
javascripttypescriptazureazure-functionsazure-cosmosdb

Internal 500 in Azure functions when using the @azure/cosmos SDK


I am working with Node 18 TypeScript azure functions and developing with VSCode. I am using the @azure/cosmos SDK to intreract with CosmosDB. I create an instance inside the functions by first creating this module:

collection.ts

import { Container, CosmosClient } from "@azure/cosmos";

const endpoint = process.env.COSMOS_DB_ENDPOINT;
const key = process.env.COSMOS_DB_KEY;

const database = process.env.COSMOS_DB_DATABASE;
const container = process.env.COSMOS_DB_COLLECTION;

export default () => {
  const client = new CosmosClient({ endpoint, key });

  return client.database(database).container(container);
};

Importing/Instantiating like so:

index.ts (some function)

import client from "collection.ts";

const collection = client();

export default async (context, req) => {...}

After some testing, I found that it fails on collection.ts:10 where I actually create the client instance (const client = new CosmosClient({ endpoint, key });). The problem is this all works in development before I deploy. I'm calling this is an internal error because I catch exceptions in the function and return an error object, but when I call a function that uses this SDK, it's not present.

I figured there was some kind of disconnect in the environments, so I added the endpoint/key/database/container env vars in the portal, and locally "Download Remote Settings..." with the vscode extention (env vars are in the Application Settings under Configuration in the portal). I have even tried hard coding strings with the correct endpoint/key instead of using process.env.

I have also tried looking at the log stream and it isn't much help:

2023-09-06T08:57:57Z   [Error]   Executed 'Functions.LoginUser' (Failed, Id=6c7dc7c5-a942-4b93-89d8-a354e1d6a868, Duration=2ms)

I'm not sure what else to try. I can provide more info if requested. Any ideas would be appreciated!


Solution

  • I have got the expected result in the following way both in local and in portal

    Created a HTTP Trigger function and then trying to invoke collection.ts file inside it. You can use Timer trigger function as well.

    collection.ts

    import { Container, CosmosClient } from  "@azure/cosmos";
    
    const  endpoint  =  process.env.COSMOS_DB_ENDPOINT;
    const  key  =  process.env.COSMOS_DB_KEY;
    const  database  =  process.env.COSMOS_DB_DATABASE;
    const  container  =  process.env.COSMOS_DB_COLLECTION;
    
    export  default () => {
    const  client  =  new  CosmosClient({ endpoint, key });
    return  client.database(database).container(container);
    };
    

    httpTrigger.ts

    import { app, HttpRequest, HttpResponseInit, InvocationContext } from  "@azure/functions";
    import  client  from  "./collection";
    
    const  collection  =  client();
    
    export  default  async  function  httpTrigger1(request:  HttpRequest, context:  InvocationContext):  Promise<HttpResponseInit> {
    context.log(`Cosmos DB data:`,collection);
    context.log(`Http function processed request for url "${request.url}"`);
    const  name  =  request.query.get('name') ||  await  request.text() ||  'world';
    return { body:  `Hello, ${name}!` };
    };
    app.http('httpTrigger1', {
    methods: ['GET', 'POST'],
    authLevel:  'anonymous',
    handler:  httpTrigger1
    });
    

    local.settings.json

    {
    
    "IsEncrypted": false,
    "Values": {
    
    "AzureWebJobsStorage": "UseDevelopmentStorage=true",
    "FUNCTIONS_WORKER_RUNTIME": "node",
    "AzureWebJobsFeatureFlags": "EnableWorkerIndexing",
    "COSMOS_DB_ENDPOINT": "<Enter Cosmos DB endpoint here>",
    "COSMOS_DB_KEY": "<Enter Cosmos DB Key here>",
    "COSMOS_DB_DATABASE": "<Cosmos DB Database Name>",
    "COSMOS_DB_COLLECTION": "<Cosmos DB Container Name>"
    
    }
    }
    

    Local Output:

    Local Output1

    Local Output2

    After deployment, I have added the credentials in Function App's App Settings.

    I triggered the function and got the expected Output.