calcom/cal.diy · error · HttpException

httpError?.message ?? errMsg

Error message

httpError?.message ?? errMsg

What it means

This is the message expression inside handleBookingErrors when the caught error is an instance of HttpError (Cal.com's domain error class with statusCode, message, url, method fields). The handler wraps it into a NestJS HttpException, preserving the original statusCode (defaulting to 500) and message (defaulting to the contextual errMsg like 'Error while creating recurring booking.'). It surfaces the upstream service's HTTP error to the API v2 caller.

Source

Thrown at apps/api/v2/src/platform/bookings/2024-04-15/controllers/bookings.controller.ts:593

    if (requestBody?.responses?.guests?.length) {
      requestBody.responses.guests = await this.platformBookingsService.getPlatformAttendeesEmails(
        requestBody.responses.guests,
        oAuthClientId
      );
    }
  }

  private handleBookingErrors(
    err: Error | HttpError | unknown,
    type?: "recurring" | `instant` | "no-show"
  ): void {
    const errMsg =
      type === "no-show"
        ? `Error while marking no-show.`
        : `Error while creating ${type ? `${type} ` : ""}booking.`;
    if (err instanceof HttpError) {
      const httpError = err as HttpError;
      throw new HttpException(httpError?.message ?? errMsg, httpError?.statusCode ?? 500);
    }

    if (err instanceof Error) {
      const error = err as Error;
      if (err instanceof HttpException) {
        throw new HttpException(err.getResponse(), err.getStatus());
      }
      if (Object.values(ErrorCode).includes(error.message as unknown as ErrorCode)) {
        throw new HttpException(error.message, 400);
      }
      throw new InternalServerErrorException(error?.message ?? errMsg);
    }

    throw new InternalServerErrorException(errMsg);
  }

  private transformToBoolean(v?: string): boolean {
    return v && typeof v === "string" ? v.toLowerCase() === "true" : false;

View on GitHub (pinned to 176037d0af)

Solutions

  1. Read the statusCode in the HTTP response — it reflects the original HttpError.statusCode and indicates the real problem (409 conflict, 402 payment, 400 bad request, etc.).
  2. Address the root cause indicated by the statusCode: resolve scheduling conflicts, retry payments, fix input validation errors.
  3. If the message is unhelpful, check server logs where the original HttpError was logged with its url, method, and data fields.
  4. Ensure your client handles the full range of status codes (400, 402, 409, 500) that the booking service can emit.
Defensive patterns

Strategy: try-catch

Try / catch

// Client-side: handle the propagated HttpError status codes
try {
  await api.createBooking(payload);
} catch (err) {
  switch (err.statusCode) {
    case 409: handleConflict(); break;
    case 402: handlePaymentFailure(); break;
    case 400: handleValidationError(err.message); break;
    default: handleGenericError(err);
  }
}

Prevention

When it happens

Trigger: Any booking creation, cancellation, no-show, or recurring booking flow where the underlying service (regularBookingService, recurringBookingService, handleCancelBooking, handleMarkNoShow) throws a HttpError — for example when an availability check fails, a payment provider returns an error, or a conferencing integration call fails upstream.

Common situations: The booking service throws HttpError with a specific status like 409 for booking conflicts, 402 for payment failures, or 400 for bad input. The message and statusCode from the HttpError are forwarded. Common during double-booking attempts, expired payment sessions, or when an app-store integration (e.g., Stripe, Zoom) returns an error.

Related errors


AI-assisted analysis of calcom/cal.diy@176037d0af (2026-08-12). Data as JSON: /api/errors/230e54ee8f9725ee. Report an issue: GitHub.