Hostrail Docs
Execution Guides

How do I handle errors?

Build resilient Hostrail integrations using error.code matching, next_actions recovery, and structured detail fields.

Metadata JSONDocs Graph

Hostrail is designed so a runtime can recover from booking failures without guessing. Errors are part of the execution contract, not an afterthought.

The three-step pattern

  1. Match on error.code — not HTTP status. Multiple codes share 409.
  2. Follow next_actions — typed recovery calls with rel, method, href.
  3. Read detail — structured data (IDs, states, amounts) for context.

Implementation

def handle_response(response):
    if "data" in response:
        return response["data"]

    error = response["error"]
    if error["code"] == "hold_expired":
        action = find_action(error["next_actions"], rel="requote")
        return call(action["method"], action["href"], original_params)
    elif error["code"] == "payment_failed":
        return ask_user_for_new_payment(error["detail"]["provider_message"])
    elif error["code"] == "rate_limited":
        sleep(error["retry_after"])
        return retry()
    else:
        log(f"{error['code']}: {error['remediation']}")
        if error["next_actions"]:
            return call(error["next_actions"][0])
        raise UnrecoverableError(error["code"], error["trace_id"])

Common scenarios

Network failure during booking

The booking endpoint is idempotent. Retry with the same Idempotency-Key — you'll get the cached response (success or sealed error).

Two agents book the same room

Inventory protected by holds. Only one agent can hold a room at a time — the second gets allocation_failed (409).

Rate limiting

Default: 100 req/min per tenant. Back off for retry_after seconds. For sustained traffic, implement a token bucket.

Markdown or hotel-page copy disagrees with quote output

Treat quote output as authoritative. Root-site discovery surfaces such as llms.txt and llms-full.txt are useful for planning and retrieval, but live price and cancellation terms are confirmed in the quote response.

Error lookup table

Fetch GET /.well-known/errors once at startup:

catalog = fetch("GET /.well-known/errors")
error_lookup = {e["code"]: e for e in catalog["errors"]}

Also keep the docs site handy through each error's docs_url, which deep-links back into the canonical explanation.

On this page