feat: dist tracing 4 (#25574)
* feat: distributed tracing 2 * feat: distributed tracing 2 * refactor: feedback * refactor: feedback * fix: type error * fix: trpc error * feat: distributed tracing - 3 * chore: translation * refactor: improvements * fix: feedback * chore: remove * feat: dist tracing 4 * fix: type errors * fix: type errors * fix: remove string type * fix: type errors
This commit is contained in:
@@ -9,6 +9,7 @@ import {
|
||||
import { describe, it, beforeEach, vi, expect } from "vitest";
|
||||
|
||||
import * as handleConfirmationModule from "@calcom/features/bookings/lib/handleConfirmation";
|
||||
import { distributedTracing } from "@calcom/lib/tracing/factory";
|
||||
import { BookingStatus } from "@calcom/prisma/enums";
|
||||
import { confirmHandler } from "@calcom/trpc/server/routers/viewer/bookings/confirm.handler";
|
||||
import type { TrpcSessionUser } from "@calcom/trpc/server/types";
|
||||
@@ -92,6 +93,7 @@ describe("confirmHandler", () => {
|
||||
timeZone: organizer.timeZone,
|
||||
username: organizer.username,
|
||||
} as NonNullable<TrpcSessionUser>,
|
||||
traceContext: distributedTracing.createTrace("test_confirm_handler"),
|
||||
};
|
||||
|
||||
const res = await confirmHandler({
|
||||
|
||||
@@ -10,6 +10,7 @@ import type { z } from "zod";
|
||||
|
||||
import { appStoreMetadata } from "@calcom/app-store/appStoreMetaData";
|
||||
import { handleStripePaymentSuccess } from "@calcom/features/ee/payments/api/webhook";
|
||||
import { distributedTracing } from "@calcom/lib/tracing/factory";
|
||||
import { ProfileRepository } from "@calcom/features/profile/repositories/ProfileRepository";
|
||||
import { weekdayToWeekIndex, type WeekDays } from "@calcom/lib/dayjs";
|
||||
import type { HttpError } from "@calcom/lib/http-error";
|
||||
@@ -2287,7 +2288,8 @@ export function getMockedStripePaymentEvent({ paymentIntentId }: { paymentIntent
|
||||
export async function mockPaymentSuccessWebhookFromStripe({ externalId }: { externalId: string }) {
|
||||
let webhookResponse = null;
|
||||
try {
|
||||
await handleStripePaymentSuccess(getMockedStripePaymentEvent({ paymentIntentId: externalId }));
|
||||
const traceContext = distributedTracing.createTrace("test_stripe_webhook");
|
||||
await handleStripePaymentSuccess(getMockedStripePaymentEvent({ paymentIntentId: externalId }), traceContext);
|
||||
} catch (e) {
|
||||
log.silly("mockPaymentSuccessWebhookFromStripe:catch", JSON.stringify(e));
|
||||
webhookResponse = e as HttpError;
|
||||
|
||||
@@ -10,13 +10,19 @@ import { getPlatformParams } from "@calcom/features/platform-oauth-client/get-pl
|
||||
import { PlatformOAuthClientRepository } from "@calcom/features/platform-oauth-client/platform-oauth-client.repository";
|
||||
import { HttpError as HttpCode } from "@calcom/lib/http-error";
|
||||
import logger from "@calcom/lib/logger";
|
||||
import type { TraceContext } from "@calcom/lib/tracing";
|
||||
import { distributedTracing } from "@calcom/lib/tracing/factory";
|
||||
import prisma from "@calcom/prisma";
|
||||
import type { Prisma } from "@calcom/prisma/client";
|
||||
import { BookingStatus } from "@calcom/prisma/enums";
|
||||
import type { EventTypeMetadata } from "@calcom/prisma/zod-utils";
|
||||
|
||||
const log = logger.getSubLogger({ prefix: ["[handlePaymentSuccess]"] });
|
||||
export async function handlePaymentSuccess(paymentId: number, bookingId: number) {
|
||||
export async function handlePaymentSuccess(paymentId: number, bookingId: number, traceContext: TraceContext) {
|
||||
const updatedTraceContext = distributedTracing.updateTrace(traceContext, {
|
||||
bookingId,
|
||||
paymentId,
|
||||
});
|
||||
log.debug(`handling payment success for bookingId ${bookingId}`);
|
||||
const { booking, user: userWithCredentials, evt, eventType } = await getBooking(bookingId);
|
||||
|
||||
@@ -87,6 +93,7 @@ export async function handlePaymentSuccess(paymentId: number, bookingId: number)
|
||||
booking,
|
||||
paid: true,
|
||||
platformClientParams: platformOAuthClient ? getPlatformParams(platformOAuthClient) : undefined,
|
||||
traceContext: updatedTraceContext,
|
||||
});
|
||||
} else {
|
||||
await handleBookingRequested({
|
||||
|
||||
@@ -3,6 +3,7 @@ import getRawBody from "raw-body";
|
||||
import { z } from "zod";
|
||||
|
||||
import { handlePaymentSuccess } from "@calcom/app-store/_utils/payments/handlePaymentSuccess";
|
||||
import { distributedTracing } from "@calcom/lib/tracing/factory";
|
||||
import { albyCredentialKeysSchema } from "@calcom/app-store/alby/lib";
|
||||
import parseInvoice from "@calcom/app-store/alby/lib/parseInvoice";
|
||||
import { IS_PRODUCTION } from "@calcom/lib/constants";
|
||||
@@ -88,7 +89,10 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
||||
throw new HttpCode({ statusCode: 400, message: "invoice amount does not match payment amount" });
|
||||
}
|
||||
|
||||
return await handlePaymentSuccess(payment.id, payment.bookingId);
|
||||
const traceContext = distributedTracing.createTrace("alby_webhook", {
|
||||
meta: { paymentId: payment.id, bookingId: payment.bookingId },
|
||||
});
|
||||
return await handlePaymentSuccess(payment.id, payment.bookingId, traceContext);
|
||||
} catch (_err) {
|
||||
const err = getServerErrorFromUnknown(_err);
|
||||
console.error(`Webhook Error: ${err.message}`);
|
||||
|
||||
@@ -4,6 +4,7 @@ import getRawBody from "raw-body";
|
||||
import { z } from "zod";
|
||||
|
||||
import { handlePaymentSuccess } from "@calcom/app-store/_utils/payments/handlePaymentSuccess";
|
||||
import { distributedTracing } from "@calcom/lib/tracing/factory";
|
||||
import { IS_PRODUCTION } from "@calcom/lib/constants";
|
||||
import { HttpError as HttpCode } from "@calcom/lib/http-error";
|
||||
import { getServerErrorFromUnknown } from "@calcom/lib/server/getServerErrorFromUnknown";
|
||||
@@ -87,7 +88,10 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
||||
);
|
||||
if (!isValid) throw new HttpCode({ statusCode: 400, message: "signature mismatch" });
|
||||
|
||||
await handlePaymentSuccess(payment.id, payment.bookingId);
|
||||
const traceContext = distributedTracing.createTrace("btcpayserver_webhook", {
|
||||
meta: { paymentId: payment.id, bookingId: payment.bookingId },
|
||||
});
|
||||
await handlePaymentSuccess(payment.id, payment.bookingId, traceContext);
|
||||
return res.status(200).json({ success: true });
|
||||
} catch (_err) {
|
||||
const err = getServerErrorFromUnknown(_err);
|
||||
|
||||
@@ -3,6 +3,7 @@ import type { NextApiRequest, NextApiResponse } from "next";
|
||||
import type z from "zod";
|
||||
|
||||
import { handlePaymentSuccess } from "@calcom/app-store/_utils/payments/handlePaymentSuccess";
|
||||
import { distributedTracing } from "@calcom/lib/tracing/factory";
|
||||
import { IS_PRODUCTION } from "@calcom/lib/constants";
|
||||
import { HttpError as HttpCode } from "@calcom/lib/http-error";
|
||||
import { getServerErrorFromUnknown } from "@calcom/lib/server/getServerErrorFromUnknown";
|
||||
@@ -109,7 +110,10 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
||||
if (excluded.status !== "completed") {
|
||||
throw new HttpCode({ statusCode: 204, message: `Payment is ${excluded.status}` });
|
||||
}
|
||||
return await handlePaymentSuccess(payment.id, payment.bookingId);
|
||||
const traceContext = distributedTracing.createTrace("hitpay_webhook", {
|
||||
meta: { paymentId: payment.id, bookingId: payment.bookingId },
|
||||
});
|
||||
return await handlePaymentSuccess(payment.id, payment.bookingId, traceContext);
|
||||
} catch (_err) {
|
||||
const err = getServerErrorFromUnknown(_err);
|
||||
console.error(`Webhook Error: ${err.message}`);
|
||||
|
||||
@@ -3,6 +3,7 @@ import getRawBody from "raw-body";
|
||||
import { z } from "zod";
|
||||
|
||||
import { handlePaymentSuccess } from "@calcom/app-store/_utils/payments/handlePaymentSuccess";
|
||||
import { distributedTracing } from "@calcom/lib/tracing/factory";
|
||||
import { paypalCredentialKeysSchema } from "@calcom/app-store/paypal/lib";
|
||||
import Paypal from "@calcom/app-store/paypal/lib/Paypal";
|
||||
import { IS_PRODUCTION } from "@calcom/lib/constants";
|
||||
@@ -62,7 +63,10 @@ export async function handlePaypalPaymentSuccess(
|
||||
},
|
||||
});
|
||||
|
||||
return await handlePaymentSuccess(payment.id, payment.bookingId);
|
||||
const traceContext = distributedTracing.createTrace("paypal_webhook", {
|
||||
meta: { paymentId: payment.id, bookingId: payment.bookingId },
|
||||
});
|
||||
return await handlePaymentSuccess(payment.id, payment.bookingId, traceContext);
|
||||
}
|
||||
|
||||
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
|
||||
@@ -20,6 +20,8 @@ import getOrgIdFromMemberOrTeamId from "@calcom/lib/getOrgIdFromMemberOrTeamId";
|
||||
import { getTeamIdFromEventType } from "@calcom/lib/getTeamIdFromEventType";
|
||||
import logger from "@calcom/lib/logger";
|
||||
import { safeStringify } from "@calcom/lib/safeStringify";
|
||||
import type { TraceContext } from "@calcom/lib/tracing";
|
||||
import { distributedTracing } from "@calcom/lib/tracing/factory";
|
||||
import type { PrismaClient } from "@calcom/prisma";
|
||||
import type { Prisma } from "@calcom/prisma/client";
|
||||
import type { SchedulingType } from "@calcom/prisma/enums";
|
||||
@@ -74,6 +76,7 @@ export async function handleConfirmation(args: {
|
||||
paid?: boolean;
|
||||
emailsEnabled?: boolean;
|
||||
platformClientParams?: PlatformClientParams;
|
||||
traceContext: TraceContext;
|
||||
}) {
|
||||
const {
|
||||
user,
|
||||
@@ -85,6 +88,7 @@ export async function handleConfirmation(args: {
|
||||
paid,
|
||||
emailsEnabled = true,
|
||||
platformClientParams,
|
||||
traceContext,
|
||||
} = args;
|
||||
const eventType = booking.eventType;
|
||||
const eventTypeMetadata = EventTypeMetaDataSchema.parse(eventType?.metadata || {});
|
||||
@@ -96,13 +100,17 @@ export async function handleConfirmation(args: {
|
||||
const metadata: AdditionalInformation = {};
|
||||
const workflows = await getAllWorkflowsFromEventType(eventType, booking.userId);
|
||||
|
||||
const spanContext = distributedTracing.createSpan(traceContext, "handle_confirmation");
|
||||
|
||||
const tracingLogger = distributedTracing.getTracingLogger(spanContext);
|
||||
|
||||
if (results.length > 0 && results.every((res) => !res.success)) {
|
||||
const error = {
|
||||
errorCode: "BookingCreatingMeetingFailed",
|
||||
message: "Booking failed",
|
||||
};
|
||||
|
||||
log.error(`Booking ${user.username} failed`, safeStringify({ error, results }));
|
||||
tracingLogger.error(`Booking ${user.username} failed`, safeStringify({ error, results }));
|
||||
} else {
|
||||
if (results.length) {
|
||||
// TODO: Handle created event metadata more elegantly
|
||||
@@ -139,7 +147,7 @@ export async function handleConfirmation(args: {
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
log.error(error);
|
||||
tracingLogger.error(error);
|
||||
}
|
||||
}
|
||||
let updatedBookings: {
|
||||
@@ -358,6 +366,7 @@ export async function handleConfirmation(args: {
|
||||
hideBranding: !!updatedBookings[index].eventType?.owner?.hideBranding,
|
||||
seatReferenceUid: evt.attendeeSeatId,
|
||||
isPlatformNoEmail: !emailsEnabled && Boolean(platformClientParams?.platformClientId),
|
||||
traceContext: spanContext,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -487,7 +496,7 @@ export async function handleConfirmation(args: {
|
||||
sub,
|
||||
payload
|
||||
).catch((e) => {
|
||||
log.error(
|
||||
tracingLogger.error(
|
||||
`Error executing webhook for event: ${WebhookTriggerEvents.BOOKING_CREATED}, URL: ${sub.subscriberUrl}, bookingId: ${evt.bookingId}, bookingUid: ${evt.uid}, platformClientId: ${platformClientParams?.platformClientId}`,
|
||||
safeStringify(e)
|
||||
);
|
||||
@@ -547,7 +556,7 @@ export async function handleConfirmation(args: {
|
||||
sub,
|
||||
payload
|
||||
).catch((e) => {
|
||||
log.error(
|
||||
tracingLogger.error(
|
||||
`Error executing webhook for event: ${WebhookTriggerEvents.BOOKING_PAID}, URL: ${sub.subscriberUrl}, bookingId: ${evt.bookingId}, bookingUid: ${evt.uid}`,
|
||||
safeStringify(e)
|
||||
);
|
||||
@@ -586,7 +595,10 @@ export async function handleConfirmation(args: {
|
||||
creditCheckFn: creditService.hasAvailableCredits.bind(creditService),
|
||||
});
|
||||
} catch (error) {
|
||||
log.error("Error while scheduling workflow reminders for booking paid", safeStringify(error));
|
||||
tracingLogger.error(
|
||||
"Error while scheduling workflow reminders for booking paid",
|
||||
safeStringify(error)
|
||||
);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
|
||||
@@ -34,6 +34,7 @@ const handleSeats = async (newSeatedBookingObject: NewSeatedBookingObject) => {
|
||||
rescheduledBy,
|
||||
rescheduleReason,
|
||||
isDryRun = false,
|
||||
traceContext,
|
||||
} = newSeatedBookingObject;
|
||||
// TODO: We could allow doing more things to support good dry run for seats
|
||||
if (isDryRun) return;
|
||||
@@ -160,7 +161,7 @@ const handleSeats = async (newSeatedBookingObject: NewSeatedBookingObject) => {
|
||||
rescheduledBy,
|
||||
};
|
||||
|
||||
await handleWebhookTrigger({ subscriberOptions, eventTrigger, webhookData, isDryRun });
|
||||
await handleWebhookTrigger({ subscriberOptions, eventTrigger, webhookData, isDryRun, traceContext });
|
||||
}
|
||||
|
||||
return resultBooking;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import type z from "zod";
|
||||
|
||||
import type { Workflow } from "@calcom/features/ee/workflows/lib/types";
|
||||
import type { TraceContext } from "@calcom/lib/tracing";
|
||||
import type { Prisma } from "@calcom/prisma/client";
|
||||
import type { AppsStatus, CalendarEvent } from "@calcom/types/Calendar";
|
||||
|
||||
@@ -58,6 +59,7 @@ export type NewSeatedBookingObject = {
|
||||
rescheduledBy?: string;
|
||||
workflows: Workflow[];
|
||||
isDryRun?: boolean;
|
||||
traceContext: TraceContext;
|
||||
};
|
||||
|
||||
export type RescheduleSeatedBookingObject = NewSeatedBookingObject & { rescheduleUid: string };
|
||||
|
||||
@@ -2,25 +2,33 @@ import getWebhooks from "@calcom/features/webhooks/lib/getWebhooks";
|
||||
import type { GetSubscriberOptions } from "@calcom/features/webhooks/lib/getWebhooks";
|
||||
import sendPayload from "@calcom/features/webhooks/lib/sendOrSchedulePayload";
|
||||
import { isEventPayload, type WebhookPayloadType } from "@calcom/features/webhooks/lib/sendPayload";
|
||||
import logger from "@calcom/lib/logger";
|
||||
import { safeStringify } from "@calcom/lib/safeStringify";
|
||||
import { withReporting } from "@calcom/lib/sentryWrapper";
|
||||
import type { TraceContext } from "@calcom/lib/tracing";
|
||||
import { distributedTracing } from "@calcom/lib/tracing/factory";
|
||||
|
||||
async function _handleWebhookTrigger(args: {
|
||||
subscriberOptions: GetSubscriberOptions;
|
||||
eventTrigger: string;
|
||||
webhookData: WebhookPayloadType;
|
||||
isDryRun?: boolean;
|
||||
traceContext: TraceContext;
|
||||
}) {
|
||||
const spanContext = distributedTracing.createSpan(args.traceContext, "webhook_trigger", {
|
||||
eventTrigger: args.eventTrigger || "unknown",
|
||||
});
|
||||
|
||||
const tracingLogger = distributedTracing.getTracingLogger(spanContext);
|
||||
try {
|
||||
if (args.isDryRun) return;
|
||||
|
||||
const subscribers = await getWebhooks(args.subscriberOptions);
|
||||
|
||||
const promises = subscribers.map((sub) =>
|
||||
sendPayload(sub.secret, args.eventTrigger, new Date().toISOString(), sub, args.webhookData).catch(
|
||||
(e) => {
|
||||
if (isEventPayload(args.webhookData)) {
|
||||
logger.error(
|
||||
tracingLogger.error(
|
||||
`Error executing webhook for event: ${args.eventTrigger}, URL: ${sub.subscriberUrl}, booking id: ${args.webhookData.bookingId}, booking uid: ${args.webhookData.uid}`,
|
||||
safeStringify(e)
|
||||
);
|
||||
@@ -30,7 +38,7 @@ async function _handleWebhookTrigger(args: {
|
||||
);
|
||||
await Promise.all(promises);
|
||||
} catch (error) {
|
||||
logger.error("Error while sending webhook", error);
|
||||
tracingLogger.error("Error while sending webhook", error);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1720,6 +1720,7 @@ async function handler(
|
||||
workflows,
|
||||
rescheduledBy: reqBody.rescheduledBy,
|
||||
isDryRun,
|
||||
traceContext,
|
||||
});
|
||||
|
||||
if (newBooking) {
|
||||
@@ -2480,6 +2481,7 @@ async function handler(
|
||||
paymentId: payment?.id,
|
||||
},
|
||||
isDryRun,
|
||||
traceContext,
|
||||
});
|
||||
|
||||
try {
|
||||
@@ -2617,6 +2619,7 @@ async function handler(
|
||||
eventTrigger,
|
||||
webhookData,
|
||||
isDryRun,
|
||||
traceContext,
|
||||
});
|
||||
} else {
|
||||
// if eventType requires confirmation we will trigger the BOOKING REQUESTED Webhook
|
||||
@@ -2628,6 +2631,7 @@ async function handler(
|
||||
eventTrigger,
|
||||
webhookData,
|
||||
isDryRun,
|
||||
traceContext,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2671,6 +2675,7 @@ async function handler(
|
||||
seatReferenceUid: evt.attendeeSeatId,
|
||||
isPlatformNoEmail: noEmail && Boolean(platformClientId),
|
||||
isDryRun,
|
||||
traceContext,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,8 @@ import { HttpError as HttpCode } from "@calcom/lib/http-error";
|
||||
import logger from "@calcom/lib/logger";
|
||||
import { safeStringify } from "@calcom/lib/safeStringify";
|
||||
import { getServerErrorFromUnknown } from "@calcom/lib/server/getServerErrorFromUnknown";
|
||||
import type { TraceContext } from "@calcom/lib/tracing";
|
||||
import { distributedTracing } from "@calcom/lib/tracing/factory";
|
||||
import { prisma } from "@calcom/prisma";
|
||||
import type { Prisma } from "@calcom/prisma/client";
|
||||
import { BookingStatus } from "@calcom/prisma/enums";
|
||||
@@ -30,7 +32,7 @@ export const config = {
|
||||
},
|
||||
};
|
||||
|
||||
export async function handleStripePaymentSuccess(event: Stripe.Event) {
|
||||
export async function handleStripePaymentSuccess(event: Stripe.Event, traceContext: TraceContext) {
|
||||
const paymentIntent = event.data.object as Stripe.PaymentIntent;
|
||||
const payment = await prisma.payment.findFirst({
|
||||
where: {
|
||||
@@ -48,10 +50,10 @@ export async function handleStripePaymentSuccess(event: Stripe.Event) {
|
||||
}
|
||||
if (!payment?.bookingId) throw new HttpCode({ statusCode: 204, message: "Payment not found" });
|
||||
|
||||
await handlePaymentSuccess(payment.id, payment.bookingId);
|
||||
await handlePaymentSuccess(payment.id, payment.bookingId, traceContext);
|
||||
}
|
||||
|
||||
const handleSetupSuccess = async (event: Stripe.Event) => {
|
||||
const handleSetupSuccess = async (event: Stripe.Event, traceContext: TraceContext) => {
|
||||
const setupIntent = event.data.object as Stripe.SetupIntent;
|
||||
const payment = await prisma.payment.findFirst({
|
||||
where: {
|
||||
@@ -63,6 +65,10 @@ const handleSetupSuccess = async (event: Stripe.Event) => {
|
||||
|
||||
const { booking, user, evt, eventType } = await getBooking(payment.bookingId);
|
||||
|
||||
const updatedTraceContext = distributedTracing.updateTrace(traceContext, {
|
||||
bookingId: booking.id,
|
||||
});
|
||||
|
||||
const bookingData: Prisma.BookingUpdateInput = {
|
||||
paid: true,
|
||||
};
|
||||
@@ -126,6 +132,7 @@ const handleSetupSuccess = async (event: Stripe.Event) => {
|
||||
booking,
|
||||
paid: true,
|
||||
platformClientParams: platformOAuthClient ? getPlatformParams(platformOAuthClient) : undefined,
|
||||
traceContext: updatedTraceContext,
|
||||
});
|
||||
} else if (areEmailsEnabled) {
|
||||
await sendOrganizerRequestEmail({ ...evt }, eventType.metadata);
|
||||
@@ -133,7 +140,7 @@ const handleSetupSuccess = async (event: Stripe.Event) => {
|
||||
}
|
||||
};
|
||||
|
||||
type WebhookHandler = (event: Stripe.Event) => Promise<void>;
|
||||
type WebhookHandler = (event: Stripe.Event, traceContext: TraceContext) => Promise<void>;
|
||||
|
||||
const webhookHandlers: Record<string, WebhookHandler | undefined> = {
|
||||
"payment_intent.succeeded": handleStripePaymentSuccess,
|
||||
@@ -163,6 +170,13 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
||||
|
||||
const event = stripe.webhooks.constructEvent(payload, sig, process.env.STRIPE_WEBHOOK_SECRET);
|
||||
|
||||
const traceContext = distributedTracing.createTrace(`stripe_webhook`, {
|
||||
meta: {
|
||||
eventType: event.type,
|
||||
eventId: event.id,
|
||||
},
|
||||
});
|
||||
|
||||
// bypassing this validation for e2e tests
|
||||
// in order to successfully confirm the payment
|
||||
if (!event.account && !process.env.NEXT_PUBLIC_IS_E2E) {
|
||||
@@ -171,7 +185,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
||||
|
||||
const handler = webhookHandlers[event.type];
|
||||
if (handler) {
|
||||
await handler(event);
|
||||
await handler(event, traceContext);
|
||||
} else {
|
||||
/** Not really an error, just letting Stripe know that the webhook was received but unhandled */
|
||||
throw new HttpCode({
|
||||
|
||||
@@ -2,14 +2,13 @@ import type { getEventTypeResponse } from "@calcom/features/bookings/lib/handleN
|
||||
import { scheduleEmailReminder } from "@calcom/features/ee/workflows/lib/reminders/emailReminderManager";
|
||||
import type { Workflow } from "@calcom/features/ee/workflows/lib/types";
|
||||
import type { getDefaultEvent } from "@calcom/features/eventtypes/lib/defaultEvents";
|
||||
import logger from "@calcom/lib/logger";
|
||||
import { withReporting } from "@calcom/lib/sentryWrapper";
|
||||
import type { TraceContext } from "@calcom/lib/tracing";
|
||||
import { distributedTracing } from "@calcom/lib/tracing/factory";
|
||||
import { WorkflowTriggerEvents, TimeUnit, WorkflowActions, WorkflowTemplates } from "@calcom/prisma/enums";
|
||||
|
||||
import type { ExtendedCalendarEvent } from "./reminderScheduler";
|
||||
|
||||
const log = logger.getSubLogger({ prefix: ["[scheduleMandatoryReminder]"] });
|
||||
|
||||
export type NewBookingEventType = Awaited<ReturnType<typeof getDefaultEvent>> | getEventTypeResponse;
|
||||
|
||||
async function _scheduleMandatoryReminder({
|
||||
@@ -20,6 +19,7 @@ async function _scheduleMandatoryReminder({
|
||||
seatReferenceUid,
|
||||
isPlatformNoEmail = false,
|
||||
isDryRun = false,
|
||||
traceContext,
|
||||
}: {
|
||||
evt: ExtendedCalendarEvent;
|
||||
workflows: Workflow[];
|
||||
@@ -28,7 +28,26 @@ async function _scheduleMandatoryReminder({
|
||||
seatReferenceUid: string | undefined;
|
||||
isPlatformNoEmail?: boolean;
|
||||
isDryRun?: boolean;
|
||||
traceContext: TraceContext;
|
||||
}) {
|
||||
const reminderMeta = {
|
||||
eventTitle: evt.title,
|
||||
attendeeCount: evt.attendees.length,
|
||||
organizerId: evt.organizer.id,
|
||||
requiresConfirmation,
|
||||
hideBranding,
|
||||
seatReferenceUid,
|
||||
isPlatformNoEmail,
|
||||
};
|
||||
|
||||
const spanContext = distributedTracing.createSpan(
|
||||
traceContext,
|
||||
"schedule_mandatory_reminder",
|
||||
reminderMeta
|
||||
);
|
||||
|
||||
const tracingLogger = distributedTracing.getTracingLogger(spanContext);
|
||||
|
||||
if (isDryRun) return;
|
||||
if (isPlatformNoEmail) return;
|
||||
try {
|
||||
@@ -67,11 +86,11 @@ async function _scheduleMandatoryReminder({
|
||||
verifiedAt: new Date(),
|
||||
});
|
||||
} catch (error) {
|
||||
log.error("Error while scheduling mandatory reminders", JSON.stringify({ error }));
|
||||
tracingLogger.error("Error while scheduling mandatory reminders", JSON.stringify({ error }));
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
log.error("Error while scheduling mandatory reminders", JSON.stringify({ error }));
|
||||
tracingLogger.error("Error while scheduling mandatory reminders", JSON.stringify({ error }));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ import { parseRecurringEvent } from "@calcom/lib/isRecurringEvent";
|
||||
import { getTranslation } from "@calcom/lib/server/i18n";
|
||||
import { PrismaOrgMembershipRepository } from "@calcom/lib/server/repository/PrismaOrgMembershipRepository";
|
||||
import { getTimeFormatStringFromUserTimeFormat } from "@calcom/lib/timeFormat";
|
||||
import type { TraceContext } from "@calcom/lib/tracing";
|
||||
import { prisma } from "@calcom/prisma";
|
||||
import { Prisma } from "@calcom/prisma/client";
|
||||
import {
|
||||
@@ -41,6 +42,7 @@ import type { TConfirmInputSchema } from "./confirm.schema";
|
||||
type ConfirmOptions = {
|
||||
ctx: {
|
||||
user: Pick<NonNullable<TrpcSessionUser>, "id" | "uuid" | "email" | "username" | "role" | "destinationCalendar">;
|
||||
traceContext: TraceContext;
|
||||
};
|
||||
input: TConfirmInputSchema;
|
||||
};
|
||||
@@ -277,6 +279,15 @@ export const confirmHandler = async ({ ctx, input }: ConfirmOptions) => {
|
||||
});
|
||||
}
|
||||
}
|
||||
const traceContext = {
|
||||
...ctx.traceContext,
|
||||
bookingUid: booking.uid || "unknown",
|
||||
confirmed: String(confirmed),
|
||||
eventTypeId: booking.eventType?.id?.toString() || "null",
|
||||
userId: user.id.toString(),
|
||||
teamId: booking.eventType?.teamId?.toString() || "null",
|
||||
};
|
||||
|
||||
if (recurringEventId && recurringEvent) {
|
||||
const groupedRecurringBookings = await prisma.booking.groupBy({
|
||||
where: {
|
||||
@@ -307,6 +318,7 @@ export const confirmHandler = async ({ ctx, input }: ConfirmOptions) => {
|
||||
(booking.eventType?.locations as LocationObject[]) || []
|
||||
);
|
||||
evt.conferenceCredentialId = conferenceCredentialId.conferenceCredentialId;
|
||||
|
||||
await handleConfirmation({
|
||||
user: { ...user, credentials: allCredentials },
|
||||
evt,
|
||||
@@ -316,6 +328,7 @@ export const confirmHandler = async ({ ctx, input }: ConfirmOptions) => {
|
||||
booking,
|
||||
emailsEnabled,
|
||||
platformClientParams,
|
||||
traceContext,
|
||||
});
|
||||
} else {
|
||||
evt.rejectionReason = rejectionReason;
|
||||
@@ -392,7 +405,7 @@ export const confirmHandler = async ({ ctx, input }: ConfirmOptions) => {
|
||||
status: BookingStatus.REJECTED,
|
||||
smsReminderNumber: booking.smsReminderNumber || undefined,
|
||||
};
|
||||
await handleWebhookTrigger({ subscriberOptions, eventTrigger, webhookData });
|
||||
await handleWebhookTrigger({ subscriberOptions, eventTrigger, webhookData, traceContext });
|
||||
|
||||
const workflows = await getAllWorkflowsFromEventType(booking.eventType, user.id);
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user