diff --git a/src/logs/api.ts b/src/logs/api.ts index 0dcece0ca..0e5c05364 100644 --- a/src/logs/api.ts +++ b/src/logs/api.ts @@ -119,9 +119,21 @@ export class LogApi { const attributes: Attributes = {}; if (telemetry.properties) { for (const [key, value] of Object.entries(telemetry.properties)) { - attributes[key] = typeof value === 'object' + // Serialize Error objects as strings to avoid serialization errors + if (value?.constructor.name === "Error") { + attributes[key] = Util.getInstance().stringify( + { + name: value.name, + message: value.message, + stack: value.stack, + cause: value.cause, + } + ); + } else { + attributes[key] = typeof value === 'object' ? Util.getInstance().stringify(value) : value; + } } } diff --git a/test/unitTests/logs/api.tests.ts b/test/unitTests/logs/api.tests.ts index a16abf0d8..0348741f4 100644 --- a/test/unitTests/logs/api.tests.ts +++ b/test/unitTests/logs/api.tests.ts @@ -63,6 +63,26 @@ describe("logs/API", () => { assert.equal(logRecord.attributes["_MS.baseType"], "TestData"); }); + it("should serialize errors", () => { + let testLogger = new TestLogger(); + let logApi = new LogApi(testLogger); + let error = new Error("test error"); + const telemetry: Telemetry = { + properties: { "testAttribute": "testValue", "error": error } + }; + const data: MonitorDomain = {}; + const logRecord = logApi["_telemetryToLogRecord"]( + telemetry, + "TestData", + data, + ) as LogRecord; + assert.equal(logRecord.body, "{}"); + assert.equal(logRecord.attributes["testAttribute"], "testValue"); + const errorStr: string = logRecord.attributes["error"] as string; + assert.ok(errorStr.includes("test error")); + assert.equal(logRecord.attributes["_MS.baseType"], "TestData"); + }); + it("trackAvailability", () => { let testLogger = new TestLogger(); let logApi = new LogApi(testLogger);