From 30ef38804cf3cff1c7012970c33f6ac36f7e66fb Mon Sep 17 00:00:00 2001 From: Pedro Castro Date: Tue, 6 Jan 2026 22:29:17 -0300 Subject: [PATCH] refactor: use structured logger in video adapters (#26285) - Remove debug console.log/console.error statements - Add logger.debug for observability (meeting lifecycle events) - Add logger.error with safe error pattern (message + name only) - Fix error messages to avoid exposing response details - Remove redundant try/catch blocks (errors propagate naturally) --- .../office365video/lib/VideoApiAdapter.ts | 5 +- .../app-store/webex/lib/VideoApiAdapter.ts | 109 ++++++++---------- 2 files changed, 55 insertions(+), 59 deletions(-) diff --git a/packages/app-store/office365video/lib/VideoApiAdapter.ts b/packages/app-store/office365video/lib/VideoApiAdapter.ts index b656707ae3..9648acb2de 100644 --- a/packages/app-store/office365video/lib/VideoApiAdapter.ts +++ b/packages/app-store/office365video/lib/VideoApiAdapter.ts @@ -1,6 +1,7 @@ import { z } from "zod"; import { triggerDelegationCredentialErrorWebhook } from "@calcom/features/webhooks/lib/triggerDelegationCredentialErrorWebhook"; +import logger from "@calcom/lib/logger"; import { CalendarAppDelegationCredentialConfigurationError, CalendarAppDelegationCredentialInvalidGrantError, @@ -266,10 +267,12 @@ const TeamsVideoApiAdapter = (credential: CredentialForCalendarServiceWithTenant if (!resultObject.id || !resultObject.joinUrl || !resultObject.joinWebUrl) { throw new HttpError({ statusCode: 500, - message: `Error creating MS Teams meeting: ${resultObject.error.message}`, + message: `Error creating MS Teams meeting: ${resultObject.error?.message || "missing required fields in response"}`, }); } + logger.debug("Teams meeting created", { meetingId: resultObject.id }); + return Promise.resolve({ type: "office365_video", id: resultObject.id, diff --git a/packages/app-store/webex/lib/VideoApiAdapter.ts b/packages/app-store/webex/lib/VideoApiAdapter.ts index bef86518f4..a8a153acff 100644 --- a/packages/app-store/webex/lib/VideoApiAdapter.ts +++ b/packages/app-store/webex/lib/VideoApiAdapter.ts @@ -1,7 +1,8 @@ import { z } from "zod"; import dayjs from "@calcom/dayjs"; -import prisma from "@calcom/prisma"; +import logger from "@calcom/lib/logger"; +import { prisma } from "@calcom/prisma"; import type { Credential } from "@calcom/prisma/client"; import type { CalendarEvent } from "@calcom/types/Calendar"; import type { CredentialPayload } from "@calcom/types/Credential"; @@ -170,47 +171,43 @@ const WebexVideoApiAdapter = (credential: CredentialPayload): VideoApiAdapter => start: meeting.start, end: meeting.end, })); - } catch (err) { - console.error(err); - + } catch { + logger.error("Error fetching Webex availability"); return []; } }, createMeeting: async (event: CalendarEvent): Promise => { /** @link https://developer.webex.com/docs/api/v1/meetings/create-a-meeting */ - try { - const response = await fetchWebexApi("meetings", { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify(translateEvent(event)), - }); - if (response.error) { - if (response.error === "invalid_grant") { - await invalidateCredential(credential.id); - return Promise.reject(new Error("Invalid grant for Cal.com webex app")); - } + const response = await fetchWebexApi("meetings", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(translateEvent(event)), + }); + if (response.error) { + if (response.error === "invalid_grant") { + await invalidateCredential(credential.id); + return Promise.reject(new Error("Invalid grant for Cal.com webex app")); } - - const result = webexEventResultSchema.parse(response); - if (result.id && result.webLink) { - return { - type: "webex_video", - id: result.id.toString(), - password: result.password || "", - url: result.webLink, - }; - } - throw new Error(`Failed to create meeting. Response is ${JSON.stringify(result)}`); - } catch (err) { - console.error(err); - throw new Error("Unexpected error"); } + + const result = webexEventResultSchema.parse(response); + if (result.id && result.webLink) { + logger.debug("Webex meeting created", { meetingId: result.id }); + return { + type: "webex_video", + id: result.id.toString(), + password: result.password || "", + url: result.webLink, + }; + } + throw new Error("Failed to create meeting: missing id or webLink in response"); }, deleteMeeting: async (uid: string): Promise => { /** @link https://developer.webex.com/docs/api/v1/meetings/delete-a-meeting */ try { + logger.debug("Deleting Webex meeting", { meetingId: uid }); const response = await fetchWebexApi(`meetings/${uid}`, { method: "DELETE", }); @@ -220,6 +217,7 @@ const WebexVideoApiAdapter = (credential: CredentialPayload): VideoApiAdapter => return Promise.reject(new Error("Invalid grant for Cal.com webex app")); } } + logger.debug("Webex meeting deleted", { meetingId: uid }); return Promise.resolve(); } catch { return Promise.reject(new Error("Failed to delete meeting")); @@ -227,35 +225,30 @@ const WebexVideoApiAdapter = (credential: CredentialPayload): VideoApiAdapter => }, updateMeeting: async (bookingRef: PartialReference, event: CalendarEvent): Promise => { /** @link https://developer.webex.com/docs/api/v1/meetings/update-a-meeting */ - try { - const response = await fetchWebexApi(`meetings/${bookingRef.uid}`, { - method: "PATCH", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify(translateEvent(event)), - }); - if (response.error) { - if (response.error === "invalid_grant") { - await invalidateCredential(credential.id); - return Promise.reject(new Error("Invalid grant for Cal.com webex app")); - } + const response = await fetchWebexApi(`meetings/${bookingRef.uid}`, { + method: "PATCH", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(translateEvent(event)), + }); + if (response.error) { + if (response.error === "invalid_grant") { + await invalidateCredential(credential.id); + return Promise.reject(new Error("Invalid grant for Cal.com webex app")); } - - const result = webexEventResultSchema.parse(response); - if (result.id && result.webLink) { - return { - type: "webex_video", - id: bookingRef.meetingId as string, - password: result.password || "", - url: result.webLink, - }; - } - throw new Error(`Failed to create meeting. Response is ${JSON.stringify(result)}`); - } catch (err) { - console.error(err); - throw new Error("Unexpected error"); } + + const result = webexEventResultSchema.parse(response); + if (result.id && result.webLink) { + return { + type: "webex_video", + id: bookingRef.meetingId as string, + password: result.password || "", + url: result.webLink, + }; + } + throw new Error("Failed to update meeting: missing id or webLink in response"); }, }; };