Save up to 17% with yearly billing

See pricing

Обработка ошибок

Кэширование и квоты: Кэширование и мониторинг.

Ошибки платформы (401, 403, 422, 429, 5xx, повторные попытки и экспоненциальная задержка (backoff), заголовки ограничения частоты запросов): Обработка ошибок.

Примеры ошибок эндпоинтов: Аэропорты · Поиск аэропортов · Радионавигационные средства.

Поиск аэропорта по коду (/airports/search)

Два разных исхода — одинаковая форма HTTP-ответа ({ "detail": "..." }), но разный смысл:

404 — ICAO не найден. Код неизвестен или отсутствует в базе данных. Типично для частных посадочных площадок, выведенных из эксплуатации аэродромов и опечаток. Покажите Аэропорт не найден и предложите пользователю проверить код ICAO.

400 — не передан ни ICAO, ни IATA. Эндпоинт требует хотя бы один идентификатор. Проверяйте ввод до вызова — пустая строка запроса приводит к 400, а не к 404.

import os
import requests

HEADERS = {
    "X-RapidAPI-Key": os.getenv("RAPIDAPI_KEY", "YOUR_RAPIDAPI_KEY"),
    "X-RapidAPI-Host": "skylink-api.p.rapidapi.com",
}
BASE = "https://skylink-api.p.rapidapi.com"


def fetch_airport(icao: str) -> dict | None:
    """Return airport data or None on 404. Raises on any other error."""
    if not icao:
        raise ValueError("ICAO code is required")
    r = requests.get(
        f"{BASE}/airports/search",
        headers=HEADERS,
        params={"icao": icao},
        timeout=(10, 15),
    )
    if r.status_code == 404:
        return None
    r.raise_for_status()
    return r.json()

404 означает, что аэропорт не найден, — это не ошибка клиента. Покажите пустое состояние и дайте пользователю повторить попытку с другим кодом.

Текстовый поиск (/airports/search/text)

УсловиеПоведение
Запрос короче 2 символов422 Unprocessable Entity
Корректный запрос, совпадений нет200 с airports: []
Корректный запрос, совпадения найдены200 с ранжированным массивом results

Пустой список airports не является ошибкой — это значит, что ни один аэропорт не подошёл под запрос. Отображайте состояние «Нет результатов», а не баннер с ошибкой.

def search_airports(query: str) -> list[dict]:
    """
    Returns a list of matching airports (may be empty).
    Raises ValueError for queries shorter than 2 characters.
    """
    if len(query) < 2:
        raise ValueError(f"Query must be at least 2 characters (got {len(query)!r})")
    r = requests.get(
        f"{BASE}/airports/search/text",
        headers=HEADERS,
        params={"q": query},
        timeout=(10, 15),
    )
    r.raise_for_status()
    return r.json().get("airports") or []
УсловиеПоведение
У аэропорта нет опубликованных радионавигационных средств200 с navaids: []
Некорректный ограничивающий прямоугольник (bounding box)400

Пустой массив navaids — это нормально: у многих небольших аэропортов нет опубликованных радионавигационных средств. Отображайте нулевое количество, а не ошибку.

def fetch_navaids(icao: str) -> list[dict]:
    """Returns navaids for an airport. Empty list is a valid result."""
    r = requests.get(
        f"{BASE}/navaids",
        headers=HEADERS,
        params={"airport": icao},
        timeout=(10, 15),
    )
    r.raise_for_status()
    return r.json().get("navaids") or []

Готовый к запуску пример

import os
import requests

HEADERS = {
    "X-RapidAPI-Key": os.getenv("RAPIDAPI_KEY", "YOUR_RAPIDAPI_KEY"),
    "X-RapidAPI-Host": "skylink-api.p.rapidapi.com",
}
BASE = "https://skylink-api.p.rapidapi.com"


def fetch_airport(icao: str) -> dict | None:
    r = requests.get(
        f"{BASE}/airports/search",
        headers=HEADERS,
        params={"icao": icao},
        timeout=(10, 15),
    )
    if r.status_code == 404:
        return None
    r.raise_for_status()
    return r.json()


def search_airports(query: str) -> list[dict]:
    if len(query) < 2:
        print(f"  [skip] query {query!r} is too short (min 2 chars)")
        return []
    r = requests.get(
        f"{BASE}/airports/search/text",
        headers=HEADERS,
        params={"q": query},
        timeout=(10, 15),
    )
    r.raise_for_status()
    return r.json().get("airports") or []


def fetch_navaids(icao: str) -> list[dict]:
    r = requests.get(
        f"{BASE}/navaids",
        headers=HEADERS,
        params={"airport": icao},
        timeout=(10, 15),
    )
    r.raise_for_status()
    return r.json().get("navaids") or []


if __name__ == "__main__":
    # 1. Fetch a known airport
    airport = fetch_airport("KJFK")
    if airport:
        print(f"Airport: {airport.get('name')} ({airport.get('icao_code')})")
    else:
        print("Airport KJFK not found")

    # 2. Try a 1-char query — gracefully skipped
    results = search_airports("K")
    print(f"1-char search results: {len(results)}")

    # 3. Valid text search
    results = search_airports("Kennedy")
    print(f"Text search 'Kennedy': {len(results)} result(s)")

    # 4. Fetch navaids — empty array is valid
    navaids = fetch_navaids("KJFK")
    print(f"Navaids at KJFK: {len(navaids)}")

Для временных сбоев (429, 5xx) используйте вспомогательную функцию повторных попыток со страницы Обработка ошибок.


См. также: Аэропорты · Поиск аэропортов · Радионавигационные средства · Кэширование и мониторинг