RoomKitBackend
Error Reference
Domain-specific error types and their codes
Overview
All RoomKit errors extend the RoomKitError base class, which provides a machine-readable code and a structured context object for programmatic error handling.
import {
RoomKitError,
BookingConflictError,
BookingNotFoundError,
InvalidStateTransitionError,
StaleVersionError,
// ... other errors
} from '@roomkit/nestjs';Base Class
class RoomKitError extends Error {
public readonly code: string;
public readonly context: Record<string, unknown>;
}All domain errors inherit from RoomKitError. You can catch RoomKitError to handle any RoomKit-specific error, or catch a specific subclass for targeted handling.
Error Types
| Error Class | Code | Context |
|---|---|---|
LocationNotFoundError | LOCATION_NOT_FOUND | { locationId } |
LocationPathConflictError | LOCATION_PATH_CONFLICT | { path } |
RoomNotFoundError | ROOM_NOT_FOUND | { roomId } |
CapacityExceededError | CAPACITY_EXCEEDED | { roomId, required, available, capacityType } |
BookingNotFoundError | BOOKING_NOT_FOUND | { bookingId } |
BookingConflictError | BOOKING_CONFLICT | { roomId, startsAt, endsAt, conflictingBookingId } |
PartitionConflictError | PARTITION_CONFLICT | { roomId, partitionRoomId, conflictingBookingId } |
InvalidStateTransitionError | INVALID_STATE_TRANSITION | { bookingId, currentStatus, attemptedStatus, allowedTransitions } |
StaleVersionError | STALE_VERSION | { bookingId, expectedVersion, actualVersion } |
InvalidTimeRangeError | INVALID_TIME_RANGE | { startsAt, endsAt, reason } |
RecurrenceConflictError | RECURRENCE_CONFLICT | { ruleId, conflictingDates } |
ExamCohortOverlapError | EXAM_COHORT_OVERLAP | { cohortId, existingSessionId, timeRange } |
BulkOperationPartialError | BULK_OPERATION_PARTIAL | { operationId, succeeded, failed, conflicts } |
BlackoutConflictError | BLACKOUT_CONFLICT | { blackoutId, locationNodeId, timeRange } |
ConfigKeyInvalidError | CONFIG_KEY_INVALID | { key, reason } |
IdempotencyConflictError | IDEMPOTENCY_CONFLICT | { idempotencyKey, existingBookingId } |
Catching Specific Errors
Use instanceof checks to handle specific error types and access their typed context.
try {
await bookingService.create(dto);
} catch (err) {
if (err instanceof BookingConflictError) {
const { roomId, conflictingBookingId } = err.context;
// Handle conflict...
}
}Examples
Handling State Transition Errors
try {
await bookingService.confirm(bookingId, 'admin-1');
} catch (err) {
if (err instanceof InvalidStateTransitionError) {
const { currentStatus, attemptedStatus, allowedTransitions } = err.context;
console.log(
`Cannot transition from ${currentStatus} to ${attemptedStatus}. ` +
`Allowed transitions: ${allowedTransitions}`,
);
}
}Handling Optimistic Concurrency
try {
await bookingService.modify(bookingId, changes, expectedVersion);
} catch (err) {
if (err instanceof StaleVersionError) {
const { expectedVersion, actualVersion } = err.context;
console.log(
`Version conflict: expected ${expectedVersion}, ` +
`but booking is at version ${actualVersion}. Refetch and retry.`,
);
}
}Handling Idempotency Conflicts
try {
await bookingService.create({
...dto,
idempotencyKey: 'meeting-2026-03-02',
});
} catch (err) {
if (err instanceof IdempotencyConflictError) {
const { existingBookingId } = err.context;
// Return the existing booking instead of creating a duplicate
return bookingService.getById(existingBookingId);
}
}Catching All RoomKit Errors
try {
await bookingService.create(dto);
} catch (err) {
if (err instanceof RoomKitError) {
console.error(`RoomKit error [${err.code}]:`, err.message);
console.error('Context:', err.context);
} else {
throw err; // Re-throw non-RoomKit errors
}
}