I have an azure function with an http trigger input that uses an output binding to write a new item into my Cosmos DB database.
The collection has a unique partition key named "channel".
When I try to create a new item using an existing partition key, the output binding fails, which I would expect. However, I cannot find any way to catch the exception, so that I can return a reasonable error message to the client.
The system returns the following:
System.Private.CoreLib: Exception while executing function: Functions.HttpTrigger-CreateGame. Microsoft.Azure.DocumentDB.Core: Entity with the specified id already exists in the system.
ResponseTime: 2020-12-31T18:34:39.2292184Z, StoreResult: StorePhysicalAddress: rntbd://cdb-ms-prod-westus1-fd37.documents.azure.com:14047/apps/158aedc4-c54a-471d-b9ab-65c0310623d5/services/c6f7e4e4-c91e-48d1-b2e5-bc58946a35b3/partitions/bd4f130f-7b26-4cc3-9b64-94c68de3bfb7/replicas/132533049153863193p/, LSN: 17, GlobalCommittedLsn: 17, PartitionKeyRangeId: 0, IsValid: True, StatusCode: 409, SubStatusCode: 0, RequestCharge: 1.57, ItemLSN: -1, SessionToken: -1#17, UsingLocalLSN: False, TransportException: null, ResourceType: Document, OperationType: Upsert
While the HTTP POST response is a 500 with no additional information.
I've tried wrapping my function in try/catch blocks, in different configurations, to no avail. When I step through my code using a debugger, I see that it completes the try portion, and never falls into the catch block -- the error appears to be thrown after all of my code has finished executing.
Is there some way to catch this exception and return my own response? Otherwise the client has no way of knowing why the call failed.
Here's my http trigger function:
import { AzureFunction, Context, HttpRequest } from '@azure/functions';
const httpTrigger: AzureFunction = async function (context: Context, req: HttpRequest): Promise<void> {
try {
context.bindings.gameData = JSON.stringify(req.body);
context.res = {
status: 201,
headers: { 'Content-Type': 'application/json' },
body: {
entry: {
affectedRows: 1,
uri: context.req.url
},
},
};
} catch (e) {
context.log(e);
context.res = {
status: 400,
headers: { 'Content-Type': 'application/json' },
body: {
errors: [
'Duplicate id',
],
},
};
}
};
export default httpTrigger;
And here's the function.json:
{
"bindings": [
{
"authLevel": "function",
"type": "httpTrigger",
"direction": "in",
"name": "req",
"methods": [
"post"
],
"route": "v1/games/"
},
{
"type": "http",
"direction": "out",
"name": "res"
},
{
"type": "cosmosDB",
"direction": "out",
"name": "gameData",
"databaseName": "myDatabase",
"collectionName": "myCollection",
"createIfNotExists": "true",
"connectionStringSetting": "AzureWebJobsStorage",
"partitionKey": "channel"
}
],
"scriptFile": "../dist/HttpTrigger-CreateGame/index.js"
}