We are using Azure Durable Functions with Typescript and the framework and runtime works great as such, but when a trigger or orchestration fails and throws an exception we are left scratching our head as to where the error actually happened.
In Application Insights, I can see the failing function and the error message but no stack trace. At best, I get a dotNet stacktrace from the framework running the function but nothing from where the actual method failed.
When googling around, I haven't been able to find any sources on how to configure this if it is at all possible. At best, I've found recommendations of using inlineSourceMap
in the Typescript compilation settings but this isn't automatically used from what I can see.
The best I've managed now is to wrap the various handlers (http, timer, servicebus) with try-catches and log at least the stacktrace of the error, even if it will be in javascript references as opposed to Typescript.
I have created a default typescript Durable function in vs code which is having below code in it.
durableHello1.ts-
import { app, HttpHandler, HttpRequest, HttpResponse, InvocationContext } from '@azure/functions';
import * as df from 'durable-functions';
import { ActivityHandler, OrchestrationContext, OrchestrationHandler } from 'durable-functions';
const activityName = 'durableHello1';
const durableHello1Orchestrator: OrchestrationHandler = function* (context: OrchestrationContext) {
const outputs = [];
outputs.push(yield context.df.callActivity(activityName, 'Tokyo'));
outputs.push(yield context.df.callActivity(activityName, 'Seattle'));
outputs.push(yield context.df.callActivity(activityName, 'Cairo'));
return outputs;
};
df.app.orchestration('durableHello1Orchestrator', durableHello1Orchestrator);
const durableHello1: ActivityHandler = (input: string): string => {
return `Hello, ${input}`;
};
df.app.activity(activityName, { handler: durableHello1 });
const durableHello1HttpStart: HttpHandler = async (request: HttpRequest, context: InvocationContext): Promise<HttpResponse> => {
const client = df.getClient(context);
const body: unknown = await request.text();
const instanceId: string = await client.startNew(request.params.orchestratorName, { input: body });
context.log(`Started orchestration with ID = '${instanceId}'.`);
return client.createCheckStatusResponse(request, instanceId);
};
app.http('durableHello1HttpStart', {
route: 'orchestrators/{orchestratorName}',
extraInputs: [df.input.durableClient()],
handler: durableHello1HttpStart,
});
host.json-
{
"version": "2.0",
"logging": {
"applicationInsights": {
"samplingSettings": {
"isEnabled": true,
"excludedTypes": "Request"
}
}
},
"extensionBundle": {
"id": "Microsoft.Azure.Functions.ExtensionBundle",
"version": "[4.*, 5.0.0)"
}
}
Then I deployed the function to the function app and invoked the function using an incorrect orchestrator function name. I am able to see the error in stack trace in application insight.