Workaround for microsoft/ApplicationInsights-node.js#1411.
Node.js v16.9+ supports Error.cause for chaining exceptions, but the Application Insights
Node.js SDK only captures the top-level error. The TelemetryExceptionData.exceptions array
always contains a single entry even though the schema supports chains via id/outerId.
By the time a processor's onEnd() or onEmit() runs, the original Error object has
already been serialized into flat OTel attributes (exception.type, exception.message,
exception.stacktrace). The .cause property is lost during this serialization — there is
no standard OTel attribute for exception cause chains.
The Azure Monitor exporter has a legacy API path: when a log record has the attribute
_MS.baseType set to "ExceptionData", the exporter uses log.body directly as
TelemetryExceptionData. This lets us construct properly formatted exception telemetry with
the full cause chain.
A helper function that:
- Traverses the
Error.causechain - Builds an array of
TelemetryExceptionDetailslinked viaid/outerId - Emits a single log record with
_MS.baseType = "ExceptionData"and the full chain as body
import { trackExceptionWithCauses } from "./trackExceptionWithCauses.js";
try {
await fetchUserProfile(userId);
} catch (error) {
// Sends ALL exceptions in the cause chain as a single telemetry item
trackExceptionWithCauses(error, "Error", { "user.id": userId });
}For an error like:
Error: Service failed
cause: Error: Repository failed
cause: Error: ECONNREFUSED
The exceptions array in Application Insights will contain:
[
{ "id": 0, "typeName": "Error", "message": "Service failed", "stack": "..." },
{ "id": 1, "outerId": 0, "typeName": "Error", "message": "Repository failed", "stack": "..." },
{ "id": 2, "outerId": 1, "typeName": "Error", "message": "ECONNREFUSED", "stack": "..." }
]npm install
# Set your connection string
export APPLICATIONINSIGHTS_CONNECTION_STRING="InstrumentationKey=..."
npm start