Save up to 17% with yearly billing

See pricing

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

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

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

Примеры 404 для эндпоинтов: METAR · TAF · Ветер на высотах.

Когда погодные данные отсутствуют

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

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

TAF 404. У аэропорта может быть METAR, но TAF для него не выпускается. Небольшие аэропорты без значительного трафика по приборам часто имеют только METAR. Запрашивайте METAR как обычно, пропускайте TAF и показывайте только текущие условия.

import requests

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


def get_weather(icao: str) -> dict:
    """
    Returns a dict with 'metar' and 'taf' keys.
    Either can be None if data is unavailable for this airport.
    """
    result = {"metar": None, "taf": None}

    r = requests.get(f"{BASE}/weather/metar/{icao}", headers=HEADERS, params={"parsed": "true"}, timeout=(10, 15))
    if r.status_code == 200:
        result["metar"] = r.json()
    elif r.status_code != 404:
        r.raise_for_status()

    r = requests.get(f"{BASE}/weather/taf/{icao}", headers=HEADERS, params={"parsed": "true"}, timeout=(10, 15))
    if r.status_code == 200:
        result["taf"] = r.json()
    elif r.status_code != 404:
        r.raise_for_status()

    return result


# weather = get_weather("KOXB")  # small airport, no TAF
# print("METAR:", "available" if weather["metar"] else "not available")
# print("TAF:",   "available" if weather["taf"]   else "not available")

Отображайте доступные данные METAR/TAF и явно помечайте пробелы (например, «Для этого аэропорта прогноза нет»). Погодный 404 означает, что продукт не публикуется для этого ICAO, а не ошибку на стороне клиента.

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

Эндпоинты на маршруте (bbox)

Ветер на высотах, PIREP и AIRMET/SIGMET используют query-параметр bbox, а не один код ICAO. Семантика ошибок отличается от METAR/TAF:

ЭндпоинтПустой результат404Примечания
Ветер на высотах-В bbox нет станций FBПокрытие только США — расширьте bbox или проверьте координаты
PIREPreports: [], total: 0- (при некорректном bbox — 400)Нет свежих донесений пилотов — это не ошибка
AIRMET/SIGMETreports: [], total: 0- (при некорректном bbox — 400)Нет активных предупреждений — обычное дело в погоду VFR
import requests

HEADERS = {
    "X-RapidAPI-Key": "YOUR_RAPIDAPI_KEY",
    "X-RapidAPI-Host": "skylink-api.p.rapidapi.com",
}
BASE = "https://skylink-api.p.rapidapi.com"
BBOX = "39,-80,42,-73"  # example corridor


def enroute_weather(bbox: str) -> dict:
    """Fetch en-route layers. Empty lists are valid - do not treat as failures."""
    out = {"winds": None, "pireps": [], "airsigmets": []}

    r = requests.get(
        f"{BASE}/weather/winds-aloft",
        headers=HEADERS,
        params={"bbox": bbox, "forecast": 12, "level": "low"},
        timeout=(10, 20),
    )
    if r.status_code == 200:
        out["winds"] = r.json()
    elif r.status_code != 404:
        r.raise_for_status()

    r = requests.get(
        f"{BASE}/weather/pireps",
        headers=HEADERS,
        params={"bbox": bbox, "hours": 3},
        timeout=(10, 20),
    )
    r.raise_for_status()
    out["pireps"] = r.json().get("reports") or []

    r = requests.get(
        f"{BASE}/weather/airsigmet",
        headers=HEADERS,
        params={"bbox": bbox, "type": "airmet"},
        timeout=(10, 25),
    )
    r.raise_for_status()
    out["airsigmets"] = r.json().get("reports") or []

    return out


# wx = enroute_weather(BBOX)
# print("Winds stations:", wx["winds"]["total"] if wx["winds"] else "none in bbox")
# print("PIREPs:", len(wx["pireps"]))
# print("AIRMETs:", len(wx["airsigmets"]))

Показывайте в интерфейсе явные пустые состояния («Нет донесений пилотов за последние 3 ч», «Нет активных AIRMET») вместо баннеров с ошибкой.


См. также: METAR · TAF · Ветер на высотах · PIREP · AIRMET/SIGMET · Паттерны для продакшна · Сценарии для аэропорта · Сценарии на маршруте