chore: Add logging to msteams (#23684)

* Add logging

* fix: Add response status checking to MS Teams adapter error handling

- Add response.ok checks before parsing JSON in createMeeting and updateMeeting
- Remove console.log statements that could leak credential information
- Ensure error handling matches original handleErrorsRaw behavior for tests

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* Fix logs

* Revert "fix: Add response status checking to MS Teams adapter error handling"

This reverts commit 35820d21e1a54d9e04d83fd5f53584d64a5459b6.

* fix: Add response status checking to MS Teams adapter error handling

- Check response.ok before parsing JSON in createMeeting and updateMeeting
- Re-throw HttpError instances instead of wrapping them in catch blocks
- This ensures HTTP errors (like 500) are properly propagated

Co-Authored-By: unknown <>

* fix: Correct log message in updateMeeting to say 'updating' instead of 'creating'

Co-Authored-By: unknown <>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
This commit is contained in:
Joe Au-Yeung
2026-01-11 10:34:02 +05:30
committed by GitHub
co-authored by Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Udit Takkar Anik Dhabal Babu
parent 8b9c3dcbb9
commit 08edd4f361
@@ -1,13 +1,12 @@
import { z } from "zod";
import { triggerDelegationCredentialErrorWebhook } from "@calcom/features/webhooks/lib/triggerDelegationCredentialErrorWebhook";
import logger from "@calcom/lib/logger";
import {
CalendarAppDelegationCredentialConfigurationError,
CalendarAppDelegationCredentialInvalidGrantError,
} from "@calcom/lib/CalendarAppError";
import { handleErrorsRaw } from "@calcom/lib/errors";
import { HttpError } from "@calcom/lib/http-error";
import logger from "@calcom/lib/logger";
import type { CalendarEvent } from "@calcom/types/Calendar";
import type { CredentialForCalendarServiceWithTenantId } from "@calcom/types/Credential";
import type { PartialReference } from "@calcom/types/EventManager";
@@ -39,6 +38,7 @@ const getO365VideoAppKeys = async () => {
};
const TeamsVideoApiAdapter = (credential: CredentialForCalendarServiceWithTenantId): VideoApiAdapter => {
const log = logger.getSubLogger({ prefix: ["TeamsVideoApiAdapter"] });
let azureUserId: string | null;
const tokenResponse = oAuthManagerHelper.getTokenObjectFromCredential(credential);
@@ -228,57 +228,92 @@ const TeamsVideoApiAdapter = (credential: CredentialForCalendarServiceWithTenant
return Promise.resolve([]);
},
updateMeeting: async (bookingRef: PartialReference, event: CalendarEvent) => {
const resultString = await auth
.requestRaw({
try {
const response = await auth.requestRaw({
url: `${await getUserEndpoint()}/onlineMeetings`,
options: {
method: "POST",
body: JSON.stringify(translateEvent(event)),
},
})
.then(handleErrorsRaw);
});
const resultObject = JSON.parse(resultString);
if (!response.ok) {
throw new HttpError({
statusCode: response.status,
message: response.statusText,
});
}
return Promise.resolve({
type: "office365_video",
id: resultObject.id,
password: "",
url: resultObject.joinWebUrl || resultObject.joinUrl,
});
const resultString = await response.text();
const resultObject = JSON.parse(resultString);
return Promise.resolve({
type: "office365_video",
id: resultObject.id,
password: "",
url: resultObject.joinWebUrl || resultObject.joinUrl,
});
} catch (error) {
log.error(`Error updating MS Teams meeting for booking ${event.uid}`, error);
if (error instanceof HttpError) {
throw error;
}
throw new HttpError({
statusCode: 500,
message: `Error updating MS Teams meeting for booking ${event.uid}`,
});
}
},
deleteMeeting: () => {
deleteMeeting:() => {
return Promise.resolve([]);
},
createMeeting: async (event: CalendarEvent): Promise<VideoCallData> => {
const url = `${await getUserEndpoint()}/onlineMeetings`;
const resultString = await auth
.requestRaw({
try {
const response = await auth.requestRaw({
url,
options: {
method: "POST",
body: JSON.stringify(translateEvent(event)),
},
})
.then(handleErrorsRaw);
});
const resultObject = JSON.parse(resultString);
if (!response.ok) {
throw new HttpError({
statusCode: response.status,
message: response.statusText,
});
}
if (!resultObject.id || !resultObject.joinUrl || !resultObject.joinWebUrl) {
const resultString = await response.text();
const resultObject = JSON.parse(resultString);
if (!resultObject.id || !resultObject.joinUrl || !resultObject.joinWebUrl) {
throw new HttpError({
statusCode: 500,
message: `Error creating MS Teams meeting: ${resultObject.error?.message || "missing required fields in response"}`,
});
}
log.debug("Teams meeting created", { meetingId: resultObject.id });
return Promise.resolve({
type: "office365_video",
id: resultObject.id,
password: "",
url: resultObject.joinWebUrl || resultObject.joinUrl,
});
} catch (error) {
log.error(`Error creating MS Teams meeting for booking ${event.uid}`, error);
if (error instanceof HttpError) {
throw error;
}
throw new HttpError({
statusCode: 500,
message: `Error creating MS Teams meeting: ${resultObject.error?.message || "missing required fields in response"}`,
message: `Error creating MS Teams meeting for booking ${event.uid}`,
});
}
logger.debug("Teams meeting created", { meetingId: resultObject.id });
return Promise.resolve({
type: "office365_video",
id: resultObject.id,
password: "",
url: resultObject.joinWebUrl || resultObject.joinUrl,
});
},
};
};