Skip to content

Commit 03c64df

Browse files
authored
fix(msteams): use formatUnknownError instead of String(err) for error logging (#59321)
Replaces String(err) with the existing formatUnknownError() utility across the msteams extension to prevent [object Object] appearing in error logs when non-Error objects are caught (e.g., Axios errors, Bot Framework SDK error objects). Fixes #53910 thanks @BradGroux
1 parent 474693b commit 03c64df

11 files changed

Lines changed: 35 additions & 27 deletions

extensions/msteams/src/channel.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import {
3030
} from "../runtime-api.js";
3131
import { msTeamsApprovalAuth } from "./approval-auth.js";
3232
import { MSTeamsChannelConfigSchema } from "./config-schema.js";
33+
import { formatUnknownError } from "./errors.js";
3334
import { resolveMSTeamsGroupToolPolicy } from "./policy.js";
3435
import type { ProbeMSTeamsResult } from "./probe.js";
3536
import {
@@ -488,7 +489,7 @@ export const msteamsPlugin: ChannelPlugin<ResolvedMSTeamsAccount, ProbeMSTeamsRe
488489
applyResolvedEntry(target, entry);
489490
});
490491
} catch (err) {
491-
runtime.error?.(`msteams resolve failed: ${String(err)}`);
492+
runtime.error?.(`msteams resolve failed: ${formatUnknownError(err)}`);
492493
markPendingLookupFailed(pending);
493494
}
494495
};

extensions/msteams/src/feedback-reflection.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
type OpenClawConfig,
1616
} from "../runtime-api.js";
1717
import type { StoredConversationReference } from "./conversation-store.js";
18+
import { formatUnknownError } from "./errors.js";
1819
import { buildReflectionPrompt, parseReflectionResponse } from "./feedback-reflection-prompt.js";
1920
import {
2021
DEFAULT_COOLDOWN_MS,
@@ -137,7 +138,7 @@ function createReflectionCaptureDispatcher(params: {
137138
typingCallbacks: noopTypingCallbacks,
138139
humanDelay: core.channel.reply.resolveHumanDelayConfig(params.cfg, params.agentId),
139140
onError: (err) => {
140-
params.log.debug?.("reflection reply error", { error: String(err) });
141+
params.log.debug?.("reflection reply error", { error: formatUnknownError(err) });
141142
},
142143
});
143144

@@ -207,7 +208,7 @@ export async function runFeedbackReflection(params: RunFeedbackReflectionParams)
207208
replyOptions: capture.replyOptions,
208209
});
209210
} catch (err) {
210-
log.error("reflection dispatch failed", { error: String(err) });
211+
log.error("reflection dispatch failed", { error: formatUnknownError(err) });
211212
return;
212213
}
213214

@@ -237,7 +238,7 @@ export async function runFeedbackReflection(params: RunFeedbackReflectionParams)
237238
learning: parsedReflection.learning,
238239
});
239240
} catch (err) {
240-
log.debug?.("failed to store reflection learning", { error: String(err) });
241+
log.debug?.("failed to store reflection learning", { error: formatUnknownError(err) });
241242
}
242243

243244
const conversationType = params.conversationRef.conversation?.conversationType?.toLowerCase();
@@ -265,7 +266,7 @@ export async function runFeedbackReflection(params: RunFeedbackReflectionParams)
265266
});
266267
log.info("sent reflection follow-up", { sessionKey });
267268
} catch (err) {
268-
log.debug?.("failed to send reflection follow-up", { error: String(err) });
269+
log.debug?.("failed to send reflection follow-up", { error: formatUnknownError(err) });
269270
}
270271
}
271272

extensions/msteams/src/monitor-handler.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { type OpenClawConfig, type RuntimeEnv } from "../runtime-api.js";
22
import type { MSTeamsConversationStore } from "./conversation-store.js";
3+
import { formatUnknownError } from "./errors.js";
34
import { buildFeedbackEvent, runFeedbackReflection } from "./feedback-reflection.js";
45
import { buildFileInfoCard, parseFileConsentInvoke, uploadToConsentUrl } from "./file-consent.js";
56
import { normalizeMSTeamsConversationId } from "./inbound.js";
@@ -168,7 +169,7 @@ async function handleFileConsentInvoke(
168169
uniqueId: consentResponse.uploadInfo.uniqueId,
169170
});
170171
} catch (err) {
171-
log.error("file upload failed", { uploadId, error: String(err) });
172+
log.error("file upload failed", { uploadId, error: formatUnknownError(err) });
172173
await context.sendActivity("File upload failed. Please try again.");
173174
} finally {
174175
removePendingUpload(uploadId);
@@ -338,7 +339,7 @@ async function handleFeedbackInvoke(
338339
userComment,
339340
log: deps.log,
340341
}).catch((err) => {
341-
deps.log.error("feedback reflection failed", { error: String(err) });
342+
deps.log.error("feedback reflection failed", { error: formatUnknownError(err) });
342343
});
343344
}
344345

@@ -372,7 +373,7 @@ export function registerMSTeamsHandlers<T extends MSTeamsActivityHandler>(
372373
},
373374
});
374375
} catch (err) {
375-
deps.log.debug?.("file consent handler error", { error: String(err) });
376+
deps.log.debug?.("file consent handler error", { error: formatUnknownError(err) });
376377
}
377378
return;
378379
}
@@ -396,7 +397,7 @@ export function registerMSTeamsHandlers<T extends MSTeamsActivityHandler>(
396397
try {
397398
await handleTeamsMessage(context as MSTeamsTurnContext);
398399
} catch (err) {
399-
deps.runtime.error?.(`msteams handler failed: ${String(err)}`);
400+
deps.runtime.error?.(`msteams handler failed: ${formatUnknownError(err)}`);
400401
}
401402
await next();
402403
});
@@ -432,15 +433,15 @@ export function registerMSTeamsHandlers<T extends MSTeamsActivityHandler>(
432433
});
433434
deps.log.info("sent welcome card");
434435
} catch (err) {
435-
deps.log.debug?.("failed to send welcome card", { error: String(err) });
436+
deps.log.debug?.("failed to send welcome card", { error: formatUnknownError(err) });
436437
}
437438
} else if (!isPersonal && msteamsCfg?.groupWelcomeCard === true) {
438439
const botName = ctx.activity?.recipient?.name ?? undefined;
439440
try {
440441
await ctx.sendActivity(buildGroupWelcomeText(botName));
441442
deps.log.info("sent group welcome message");
442443
} catch (err) {
443-
deps.log.debug?.("failed to send group welcome", { error: String(err) });
444+
deps.log.debug?.("failed to send group welcome", { error: formatUnknownError(err) });
444445
}
445446
} else {
446447
deps.log.debug?.("skipping welcome (disabled by config or conversation type)");

extensions/msteams/src/monitor-handler/message-handler.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -476,7 +476,7 @@ export function createMSTeamsMessageHandler(deps: MSTeamsMessageHandlerDeps) {
476476
threadContext = formatted;
477477
}
478478
} catch (err) {
479-
log.debug?.("failed to fetch thread history", { error: String(err) });
479+
log.debug?.("failed to fetch thread history", { error: formatUnknownError(err) });
480480
// Graceful degradation: thread history is an optional enhancement.
481481
}
482482
}
@@ -566,7 +566,7 @@ export function createMSTeamsMessageHandler(deps: MSTeamsMessageHandlerDeps) {
566566
sessionKey: ctxPayload.SessionKey ?? route.sessionKey,
567567
ctx: ctxPayload,
568568
onRecordError: (err) => {
569-
logVerboseMessage(`msteams: failed updating session meta: ${String(err)}`);
569+
logVerboseMessage(`msteams: failed updating session meta: ${formatUnknownError(err)}`);
570570
},
571571
});
572572

@@ -643,8 +643,8 @@ export function createMSTeamsMessageHandler(deps: MSTeamsMessageHandlerDeps) {
643643
});
644644
}
645645
} catch (err) {
646-
log.error("dispatch failed", { error: String(err) });
647-
runtime.error?.(`msteams dispatch failed: ${String(err)}`);
646+
log.error("dispatch failed", { error: formatUnknownError(err) });
647+
runtime.error?.(`msteams dispatch failed: ${formatUnknownError(err)}`);
648648
try {
649649
await context.sendActivity("⚠️ Something went wrong. Please try again.");
650650
} catch {
@@ -707,7 +707,7 @@ export function createMSTeamsMessageHandler(deps: MSTeamsMessageHandlerDeps) {
707707
});
708708
},
709709
onError: (err) => {
710-
runtime.error?.(`msteams debounce flush failed: ${String(err)}`);
710+
runtime.error?.(`msteams debounce flush failed: ${formatUnknownError(err)}`);
711711
},
712712
});
713713

extensions/msteams/src/monitor.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ export async function monitorMSTeamsProvider(
196196
}
197197
}
198198
} catch (err) {
199-
runtime.log?.(`msteams resolve failed; using config entries. ${String(err)}`);
199+
runtime.log?.(`msteams resolve failed; using config entries. ${formatUnknownError(err)}`);
200200
}
201201

202202
msteamsCfg = {
@@ -285,7 +285,7 @@ export async function monitorMSTeamsProvider(
285285
next();
286286
})
287287
.catch((err) => {
288-
log.debug?.(`JWT validation error: ${String(err)}`);
288+
log.debug?.(`JWT validation error: ${formatUnknownError(err)}`);
289289
res.status(401).json({ error: "Unauthorized" });
290290
});
291291
});
@@ -330,7 +330,7 @@ export async function monitorMSTeamsProvider(
330330
};
331331
const onError = (err: unknown) => {
332332
httpServer.off("listening", onListening);
333-
log.error("msteams server error", { error: String(err) });
333+
log.error("msteams server error", { error: formatUnknownError(err) });
334334
reject(err);
335335
};
336336
httpServer.once("listening", onListening);
@@ -339,15 +339,15 @@ export async function monitorMSTeamsProvider(
339339
applyMSTeamsWebhookTimeouts(httpServer);
340340

341341
httpServer.on("error", (err) => {
342-
log.error("msteams server error", { error: String(err) });
342+
log.error("msteams server error", { error: formatUnknownError(err) });
343343
});
344344

345345
const shutdown = async () => {
346346
log.info("shutting down msteams provider");
347347
return new Promise<void>((resolve) => {
348348
httpServer.close((err) => {
349349
if (err) {
350-
log.debug?.("msteams server close error", { error: String(err) });
350+
log.debug?.("msteams server close error", { error: formatUnknownError(err) });
351351
}
352352
resolve();
353353
});

extensions/msteams/src/reply-dispatcher.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ export function createMSTeamsReplyDispatcher(params: {
231231
})
232232
.then(() => {
233233
return streamController.finalize().catch((err) => {
234-
params.log.debug?.("stream finalize failed", { error: String(err) });
234+
params.log.debug?.("stream finalize failed", { error: formatUnknownError(err) });
235235
});
236236
})
237237
.finally(() => {

extensions/msteams/src/reply-stream-controller.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { ReplyPayload } from "../runtime-api.js";
2+
import { formatUnknownError } from "./errors.js";
23
import type { MSTeamsMonitorLogger } from "./monitor-types.js";
34
import type { MSTeamsTurnContext } from "./sdk-types.js";
45
import { TeamsHttpStream } from "./streaming-message.js";
@@ -28,7 +29,7 @@ export function createTeamsReplyStreamController(params: {
2829
sendActivity: (activity) => params.context.sendActivity(activity),
2930
feedbackLoopEnabled: params.feedbackLoopEnabled,
3031
onError: (err) => {
31-
params.log.debug?.(`stream error: ${err instanceof Error ? err.message : String(err)}`);
32+
params.log.debug?.(`stream error: ${formatUnknownError(err)}`);
3233
},
3334
})
3435
: undefined;

extensions/msteams/src/sdk.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { formatUnknownError } from "./errors.js";
12
import type { MSTeamsAdapter } from "./messenger.js";
23
import type { MSTeamsCredentials } from "./token.js";
34
import { buildUserAgent } from "./user-agent.js";
@@ -449,7 +450,7 @@ export function createMSTeamsAdapter(app: MSTeamsApp, sdk: MSTeamsTeamsSdk): MST
449450
}
450451
} catch (err) {
451452
if (!isInvoke) {
452-
response.status(500).send({ error: String(err) });
453+
response.status(500).send({ error: formatUnknownError(err) });
453454
}
454455
}
455456
},

extensions/msteams/src/send-context.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import type {
99
MSTeamsConversationStore,
1010
StoredConversationReference,
1111
} from "./conversation-store.js";
12+
import { formatUnknownError } from "./errors.js";
1213
import { resolveGraphChatId } from "./graph-upload.js";
1314
import type { MSTeamsAdapter } from "./messenger.js";
1415
import { getMSTeamsRuntime } from "./runtime.js";
@@ -190,7 +191,7 @@ export async function resolveMSTeamsSendContext(params: {
190191
"failed to resolve Graph chat ID; file uploads may fall back to Bot Framework ID",
191192
{
192193
conversationId,
193-
error: String(err),
194+
error: formatUnknownError(err),
194195
},
195196
);
196197
graphChatId = null;

extensions/msteams/src/setup-surface.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
type WizardPrompter,
1414
} from "openclaw/plugin-sdk/setup";
1515
import type { MSTeamsTeamConfig } from "../runtime-api.js";
16+
import { formatUnknownError } from "./errors.js";
1617
import {
1718
parseMSTeamsTeamEntry,
1819
resolveMSTeamsChannelAllowlist,
@@ -240,7 +241,7 @@ async function resolveMSTeamsGroupAllowlist(params: {
240241
return resolvedEntries;
241242
} catch (err) {
242243
await params.prompter.note(
243-
`Channel lookup failed; keeping entries as typed. ${String(err)}`,
244+
`Channel lookup failed; keeping entries as typed. ${formatUnknownError(err)}`,
244245
"MS Teams channels",
245246
);
246247
return resolvedEntries;

0 commit comments

Comments
 (0)