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)
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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<VideoCallData> => {
|
||||
/** @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<void> => {
|
||||
/** @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<VideoCallData> => {
|
||||
/** @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");
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user