Обработка ошибок
Кэширование и квоты: Кэширование и мониторинг.
Ошибки платформы (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 []Поиск радионавигационных средств (/navaids)
| Условие | Поведение |
|---|---|
| У аэропорта нет опубликованных радионавигационных средств | 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) используйте вспомогательную функцию повторных попыток со страницы Обработка ошибок.
См. также: Аэропорты · Поиск аэропортов · Радионавигационные средства · Кэширование и мониторинг