From 1c8fab89c38c4e5ca2612ff30e2921f00c0e64ef Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Wed, 26 Aug 2026 02:20:07 -0700 Subject: [PATCH] refactor(msteams): unify proactive send failure handling (#129995) --- extensions/msteams/src/send.ts | 79 ++++++++++------------------------ 1 file changed, 22 insertions(+), 57 deletions(-) diff --git a/extensions/msteams/src/send.ts b/extensions/msteams/src/send.ts index 25ee223a11ce..0b22212ee2ed 100644 --- a/extensions/msteams/src/send.ts +++ b/extensions/msteams/src/send.ts @@ -66,6 +66,16 @@ const FILE_CONSENT_THRESHOLD_BYTES = 4 * 1024 * 1024; // 4MB */ const MSTEAMS_MAX_MEDIA_BYTES = 100 * 1024 * 1024; +function createMSTeamsSendError(errorPrefix: string, error: unknown): Error { + const classification = classifyMSTeamsSendError(error); + const hint = formatMSTeamsSendErrorHint(classification); + const status = classification.statusCode ? ` (HTTP ${classification.statusCode})` : ""; + return new Error( + `${errorPrefix} failed${status}: ${formatUnknownError(error)}${hint ? ` (${hint})` : ""}`, + { cause: error }, + ); +} + function createMSTeamsSendReceipt(params: { conversationId: string; platformMessageIds: readonly string[]; @@ -333,13 +343,7 @@ export async function sendMessageMSTeams( kind: "media", }); } catch (err) { - const classification = classifyMSTeamsSendError(err); - const hint = formatMSTeamsSendErrorHint(classification); - const status = classification.statusCode ? ` (HTTP ${classification.statusCode})` : ""; - throw new Error( - `msteams file send failed${status}: ${formatUnknownError(err)}${hint ? ` (${hint})` : ""}`, - { cause: err }, - ); + throw createMSTeamsSendError("msteams file send", err); } } @@ -387,13 +391,7 @@ async function sendTextWithMedia( serviceUrlBoundary: ctx.sdkCloudOptions, }); } catch (err) { - const classification = classifyMSTeamsSendError(err); - const hint = formatMSTeamsSendErrorHint(classification); - const status = classification.statusCode ? ` (HTTP ${classification.statusCode})` : ""; - throw new Error( - `msteams send failed${status}: ${formatUnknownError(err)}${hint ? ` (${hint})` : ""}`, - { cause: err }, - ); + throw createMSTeamsSendError("msteams send", err); } const messageId = platformMessageIds[0] ?? "unknown"; @@ -439,13 +437,7 @@ async function sendProactiveActivity({ try { return await sendProactiveActivityRaw({ ctx, activity }); } catch (err) { - const classification = classifyMSTeamsSendError(err); - const hint = formatMSTeamsSendErrorHint(classification); - const status = classification.statusCode ? ` (HTTP ${classification.statusCode})` : ""; - throw new Error( - `${errorPrefix} failed${status}: ${formatUnknownError(err)}${hint ? ` (${hint})` : ""}`, - { cause: err }, - ); + throw createMSTeamsSendError(errorPrefix, err); } } @@ -544,31 +536,16 @@ export async function sendAdaptiveCardMSTeams( }; } -type EditMSTeamsMessageParams = { +type MSTeamsMessageMutationParams = { /** Full config (for credentials) */ cfg: OpenClawConfig; /** Conversation ID or user ID */ to: string; - /** Activity ID of the message to edit */ - activityId: string; - /** New message text */ - text: string; -}; - -type EditMSTeamsMessageResult = { - conversationId: string; -}; - -type DeleteMSTeamsMessageParams = { - /** Full config (for credentials) */ - cfg: OpenClawConfig; - /** Conversation ID or user ID */ - to: string; - /** Activity ID of the message to delete */ + /** Activity ID of the message to edit or delete */ activityId: string; }; -type DeleteMSTeamsMessageResult = { +type MSTeamsMessageMutationResult = { conversationId: string; }; @@ -579,8 +556,8 @@ type DeleteMSTeamsMessageResult = { * original turn context. */ export async function editMessageMSTeams( - params: EditMSTeamsMessageParams, -): Promise { + params: MSTeamsMessageMutationParams & { text: string }, +): Promise { const { cfg, to, activityId, text } = params; const { app, conversationId, ref, log, sdkCloudOptions } = await resolveMSTeamsSendContext({ cfg, @@ -603,13 +580,7 @@ export async function editMessageMSTeams( { serviceUrlBoundary: sdkCloudOptions }, ); } catch (err) { - const classification = classifyMSTeamsSendError(err); - const hint = formatMSTeamsSendErrorHint(classification); - const status = classification.statusCode ? ` (HTTP ${classification.statusCode})` : ""; - throw new Error( - `msteams edit failed${status}: ${formatUnknownError(err)}${hint ? ` (${hint})` : ""}`, - { cause: err }, - ); + throw createMSTeamsSendError("msteams edit", err); } log.info("edited proactive message", { conversationId, activityId }); @@ -624,8 +595,8 @@ export async function editMessageMSTeams( * original turn context. */ export async function deleteMessageMSTeams( - params: DeleteMSTeamsMessageParams, -): Promise { + params: MSTeamsMessageMutationParams, +): Promise { const { cfg, to, activityId } = params; const { app, conversationId, ref, log, sdkCloudOptions } = await resolveMSTeamsSendContext({ cfg, @@ -640,13 +611,7 @@ export async function deleteMessageMSTeams( serviceUrlBoundary: sdkCloudOptions, }); } catch (err) { - const classification = classifyMSTeamsSendError(err); - const hint = formatMSTeamsSendErrorHint(classification); - const status = classification.statusCode ? ` (HTTP ${classification.statusCode})` : ""; - throw new Error( - `msteams delete failed${status}: ${formatUnknownError(err)}${hint ? ` (${hint})` : ""}`, - { cause: err }, - ); + throw createMSTeamsSendError("msteams delete", err); } log.info("deleted proactive message", { conversationId, activityId });