๐Ÿšจ Booking Errors &
the Atlantis Problem

How a hard-coded 404 destination becomes a real-time error in the LaunchDarkly Observability platform โ€” captured from both the browser and the server.

๐Ÿ”ต LD Observability Browser SDK ๐Ÿ”ต LD Observability Node SDK ๐Ÿ“ Winston LDTransport

The problem

Atlantis is a destination in Toggle Travel that always fails at checkout. When a user selects Atlantis and clicks Confirm, the server returns a 404 โ€” Destination Not Found. No booking is created. The payment is never charged. The user hits a dead end.

This isn't a bug we need to fix โ€” it's a deliberate demo signal. The question is: how quickly can your observability platform surface it?

โš ๏ธ
What the user sees

A dark-red "404 โ€” Destination Not Found" banner with the server's error message, the trace ID, and a "Browse other destinations" button.

โš™๏ธ
What the server does

bookingService.js throws a 404 immediately after the destination lookup โ€” before any payment or database write. Winston logs the error, which routes to LD via the custom LDTransport.

LD Observability โ€” Errors
booking_failed_destination_unreachable
dest-013 ยท Atlantis ยท $8,000 quoted
404
Booking error: 404 โ€” Destination not found
booking.html ยท confirmBooking() ยท browser
Browser
Payment declined
booking.html ยท confirmBooking() ยท browser
402

How errors appear in the LD Observability Errors view

How it works

Two signals, one error

LaunchDarkly captures the Atlantis failure from both sides โ€” server and browser โ€” and correlates them with the same trace ID.

Signal flow

1
User clicks Confirm on Atlantis Browser sends POST /api/bookings with destinationId=dest-013
2
Server throws 404 bookingService.js detects dest-013 and throws before any payment or DB write
3
Winston logs the error logger.error('booking_failed_destination_unreachable', { destination_id, quoted_amount, session_id, โ€ฆ })
4
LDTransport forwards to LD The custom Winston transport calls LDObserve.recordLog() โ€” the log appears on the LD Observability Logs and Errors views
5
Browser catches the 404 response confirmBooking() in booking.html catches the error from the fetch call
6
Browser SDK records the error LDObserve.recordError(err, undefined, { destination_id, http_status, trace_id, โ€ฆ }) sends the browser-side event to LD with rich metadata
7
Both entries appear in LD Observability Server log + browser error are correlated by trace_id โ€” one click surfaces the full picture

Why explicit recordError?

The LD Observability browser SDK automatically captures uncaught errors (unhandled promise rejections, window.onerror). But the Atlantis 404 is caught โ€” the UI handles it to show the user a helpful banner.

If we didn't call LDObserve.recordError() manually, the SDK's auto-capture wouldn't fire and the error would be invisible to LD. Explicit recording is required any time you catch-and-display.

๐Ÿ”ต
LD records errors for every booking failure

Not just Atlantis 404s โ€” payment declines (402) and generic 5xx errors are also passed to recordError(). This means the LD Errors view reflects the full health of the booking flow, not just one failure mode.

The metadata attached to each error

LDObserve.recordError(err, undefined, {
  destination_id: 'dest-013',
  destination_name: 'Atlantis',
  quoted_amount: 8000,
  http_status: 404,
  trace_id: /* from response header */,
  page: 'booking',
  stage: 'confirm',
});

This metadata is searchable and filterable on the LD Observability Errors view โ€” you can filter to destination_id=dest-013 to see only Atlantis failures, or http_status=404 to see all not-found errors across the app.

Try it yourself

Search for Atlantis in the Oceania region, open the destination, and click Book. Hit Confirm on the payment step โ€” then check the LD Observability Errors view.

Search Oceania โ†’