Handling Errors
The Booking API has two distinct types of error responses depending on which part of the service handles the error. These have two different JSON formats so the consumer needs to be aware of both.
Important
Always rely on the HTTP status code to flag an error. The response body should be considered as details.
Schema Validation Errors
The incoming request is validated against the defined schema, both with regards to the request body and the query/path parameters. A schema validation error returns a SchemaError object.
SchemaError Format
{
"errors": {
"date": [
"The value '22023-12-12' is not valid."
]
},
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title": "One or more validation errors occurred.",
"status": 400,
"traceId": "00-145b97f392bfbd1b01b3eb9f27518a9f-d6a14e2f6f610f70-00"
}Several errors in the same request may produce multiple error properties within the errors object. This mechanism should not be relied upon however, as some errors stop further validation.
Application Errors
When business logic stops you from performing a request, an application error is raised. Unlike the schema validation error, the application error is returned as part of the standard response in an errors array.
Error Format
{
"errors": [
{
"errorCode": "INVALID_DATE",
"friendlyMessage": "The booking date needs to be in the future.",
"techMessage": "Invalid `date` query parameter.",
"exceptionReference": "1980-12-12"
}
]
}Error Codes
The errorCode is an enum of defined errors that should always have a singular underlying cause.
| Error Code | HTTP Status | Description |
|---|---|---|
BOOKING_NOT_FOUND | 404 | The path parameter bookingId is not referencing a valid id. |
ILLEGAL_STATE_CHANGE | 400 | The state is either blocked for external change, or the attempted change is not according to state flow. See Update Booking Status for allowed state changes. |
INVALID_BOOKING_ID | 400 | Invalid or missing bookingId path parameter. |
INVALID_DATE | 400 | Invalid or missing date query parameter. It follows the YYYY-MM-DD format but either points to the past or too far into the future. |
INVALID_EMAIL | 400 | Emails are validated and must pass the regex pattern ^[\w-\.]+@([\w-]+\.)+[\w-]{2,5}$. |
INVALID_GUESTCOUNT | 400 | The guestCount query parameter is either too high, has a negative value, or contains decimals. In Create/Update Booking context, refers to the guestCount in the request body. Keep in mind the restaurant could have a minimum number of guests on available tables. |
INVALID_PHONE | 400 | Phone numbers must be supplied as string, prefixed with country code and with double zero 00 replacing the plus character +. |
INVALID_STORE_ID | 400 | Invalid or missing storeId path parameter. |
INVALID_TAG | 400 | Chosen tag is not configured. |
INVALID_TIMESLOT_ID | 400 | The supplied TimeSlotId does not pass internal validation. Typically means it has added whitespace or missing characters. |
INVALID_TYPE | 400 | One or more of the supplied types are unknown. All values must be pre-configured in Munu. |
MISSING_BOOKING_OBJECT | 400 | An empty Booking object was sent. |
MISSING_GUEST_OBJECT | 400 | The Booking object is missing the Guest object in the request body, or its value is null. |
RESOURCE_LOCKED | 403 | Changes to the assigned table is not allowed. Contact the Venue to unlock the table for this Booking. |
VENUE_CLOSED | 400 | The Venue is closed. |
VENUE_NOT_FOUND | 404 | The path parameter venueId is not referencing a valid id. See List Venues for a complete list. |
TIMESLOT_NOT_FOUND | 404 | The supplied TimeSlotId cannot be found in the context of the supplied venueId. |
TIMESLOT_NOT_AVAILABLE | 400 | The supplied TimeSlotId is no longer available for Booking. Typically means the Venue is at max capacity at the specified TimeSlot. |
WAITLIST_NOT_SUPPORTED | 400 | The given Scenario or TimeSlotId does not support waitlists. |
UNDEFINED_ERROR | 500 | Any undefined error returns with this value. If the error is reproducible, our support team would love details on how to reproduce it. |
Example Error Handling
async function createBooking(bookingData) {
try {
const response = await fetch('/venues/{venueId}/bookings', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-KEY': 'your-api-key'
},
body: JSON.stringify(bookingData)
});
if (!response.ok) {
const errorBody = await response.json();
// Check for schema validation error
if (errorBody.errors && typeof errorBody.errors === 'object' && !Array.isArray(errorBody.errors)) {
console.error('Schema validation error:', errorBody.errors);
return;
}
// Handle application error
if (errorBody.errors && Array.isArray(errorBody.errors)) {
const error = errorBody.errors[0];
console.error(`Error ${error.errorCode}: ${error.friendlyMessage}`);
return;
}
}
return await response.json();
} catch (error) {
console.error('Network error:', error);
}
}