Обработка ошибков маршрутизации

При работе с маршрутизацией в экосистеме Mapbox GL JS ошибки возникают на нескольких уровнях: клиентская визуализация, сетевые запросы к API, обработка геоданных и логика построения маршрута. В реальных приложениях маршрутизация почти всегда опирается на внешние сервисы, такие как Mapbox Directions API, предоставляемые платформой Mapbox, поэтому корректная обработка ошибок становится частью архитектуры приложения, а не вспомогательной деталью.

Ошибки маршрутизации условно делятся на следующие категории:

  • сетевые сбои при запросах к API
  • ошибки авторизации и токенов доступа
  • некорректные входные координаты
  • отсутствие маршрута между точками
  • превышение лимитов API
  • ошибки обработки GeoJSON-данных на стороне клиента
  • сбои обновления источников данных в карте

Каждая из категорий требует отдельной стратегии обработки, поскольку влияет на разные уровни стека Mapbox GL JS.


Сетевой уровень и обработка HTTP-ошибок

Маршрут обычно запрашивается через HTTP(S) с использованием fetch, axios или встроенных клиентов SDK. На этом уровне наиболее частые проблемы:

  • таймаут соединения
  • потеря интернет-соединения
  • DNS-ошибки
  • HTTP 4xx и 5xx ответы

Типичная обработка через fetch:

async function getRoute(url) {
  try {
    const response = await fetch(url);

    if (!response.ok) {
      throw new Error(`HTTP ошибка: ${response.status}`);
    }

    const data = await response.json();
    return data;
  } catch (error) {
    console.error("Ошибка запроса маршрута:", error);
    return null;
  }
}

На практике важно различать:

  • 4xx ошибки — ошибка клиента (неверные параметры, токен, координаты)
  • 5xx ошибки — сбой сервиса маршрутизации Mapbox
  • сетевые ошибки — отсутствие соединения

Для маршрутизации критично предусматривать повторные запросы с экспоненциальной задержкой, особенно при временных сбоях API.


Ошибки авторизации и токена доступа

Маршрутизация в Mapbox GL JS требует корректного access token. Ошибки токена проявляются как:

  • 401 Unauthorized
  • 403 Forbidden
  • пустые ответы API

Причины:

  • истекший токен
  • ограничение по домену
  • превышение квоты
  • отсутствие доступа к Directions API

Обработка подобных ошибок должна быть явной, так как повторные запросы не решают проблему:

if (response.status === 401 || response.status === 403) {
  throw new Error("Ошибка авторизации Mapbox API");
}

При использовании Mapbox GL JS такие ошибки часто проявляются не сразу, а через цепочку визуальных симптомов: отсутствие линии маршрута, пустой GeoJSON или некорректный слой.


Некорректные координаты и валидация входных данных

Одной из наиболее частых причин ошибок маршрутизации являются неправильные координаты:

  • перепутанный порядок [lat, lng] вместо [lng, lat]
  • значения вне допустимого диапазона
  • NaN или undefined
  • отсутствие обязательных точек маршрута

Mapbox Directions API требует строгого формата координат:

longitude,latitude;longitude,latitude

Перед отправкой запроса необходимо проводить валидацию:

function isValidCoord(coord) {
  return Array.isArray(coord) &&
    coord.length === 2 &&
    Math.abs(coord[0]) <= 180 &&
    Math.abs(coord[1]) <= 90;
}

Ошибка на этом уровне часто приводит к тому, что API возвращает 422 Unprocessable Entity или пустой маршрут.


Обработка отсутствия маршрута между точками

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

  • точки находятся на разных изолированных дорожных графах
  • отсутствует доступный путь (например, острова без мостов)
  • ограничения транспорта (пешеходный/автомобильный режим)

Ответ API обычно содержит поле routes: [].

Корректная обработка:

if (!data.routes || data.routes.length === 0) {
  console.warn("Маршрут не найден");
  return null;
}

На уровне визуализации в Mapbox GL JS это означает, что слой LineString не должен обновляться или должен быть очищен.


Ошибки обновления источников данных (GeoJSON Source)

Маршрут в Mapbox GL JS часто отображается через geojson source:

map.addSource("route", {
  type: "geojson",
  data: {
    type: "Feature",
    geometry: {
      type: "LineString",
      coordinates: []
    }
  }
});

Ошибки возникают при:

  • передаче null вместо объекта GeoJSON
  • обновлении источника до его добавления на карту
  • несоответствии структуры FeatureCollection
  • попытке обновить удалённый source

Типичная защита:

const source = map.getSource("route");

if (source && data) {
  source.setData(data);
}

На практике многие ошибки маршрутизации проявляются именно здесь, а не на уровне API.


Обработка событий ошибок карты Mapbox GL JS

В Mapbox GL JS предусмотрено событие error, которое позволяет отлавливать низкоуровневые сбои рендера и загрузки ресурсов:

map.on("error", (e) => {
  console.error("Ошибка карты:", e.error);
});

Частые причины:

  • недоступные тайлы
  • ошибки стилей
  • проблемы с источниками данных
  • сбои WebGL контекста

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


Ограничения API и rate limiting

API маршрутизации Mapbox имеет ограничения по количеству запросов. При превышении лимита возвращается:

  • 429 Too Many Requests

Обработка:

if (response.status === 429) {
  console.warn("Превышен лимит запросов маршрута");
  return null;
}

Стратегии устойчивости включают:

  • очередь запросов
  • дебаунс пользовательского ввода
  • кэширование маршрутов
  • повтор с задержкой

Игнорирование rate limiting приводит к каскадным ошибкам отображения маршрутов в интерфейсе.


Асинхронные гонки и устаревшие маршруты

При интерактивных приложениях (перетаскивание точек маршрута) часто возникает проблема устаревших запросов:

  • пользователь изменил точку назначения
  • предыдущий запрос ещё не завершён
  • приходит ответ старого маршрута

Решение — использование AbortController:

let controller;

async function requestRoute(url) {
  if (controller) controller.abort();

  controller = new AbortController();

  const response = await fetch(url, {
    signal: controller.signal
  });

  return response.json();
}

Это предотвращает наложение маршрутов и неконсистентное состояние карты.


Ошибки формата GeoJSON маршрута

Mapbox GL JS строго требует корректного GeoJSON:

Частые ошибки:

  • отсутствует type
  • координаты не массив массивов
  • нарушена структура FeatureCollection
  • неверный порядок координат

Корректный маршрут:

{
  "type": "Feature",
  "geometry": {
    "type": "LineString",
    "coordinates": [
      [69.5901, 42.3170],
      [69.2200, 41.3100]
    ]
  }
}

Любое отклонение приводит к тихому сбою отрисовки без явной ошибки в UI.


Логирование и диагностика маршрутизации

Сложные ошибки маршрутов часто требуют многоуровневого логирования:

  • входные координаты
  • параметры запроса
  • HTTP статус
  • ответ API
  • итоговый GeoJSON

Пример диагностического слоя:

function logRouteDebug(input, response) {
  console.log("INPUT:", input);
  console.log("STATUS:", response.status);
  console.log("ROUTES:", response.routes?.length);
}

Такая детализация особенно важна при интеграции с динамическими интерфейсами и внешними сервисами маршрутизации.


Поведение интерфейса при ошибках маршрута

При сбое маршрутизации карта не должна оставаться в неопределённом состоянии. Возможные сценарии:

  • очистка слоя маршрута
  • отображение предыдущего валидного маршрута
  • скрытие линии маршрута
  • блокировка UI до завершения запроса

В Mapbox GL JS состояние карты и источников данных асинхронно, поэтому визуальная консистентность полностью зависит от прикладной логики.


Объединение стратегий обработки ошибок

Эффективная обработка ошибок маршрутизации строится как многоуровневая система:

  • валидация данных до запроса
  • контроль HTTP-ответов
  • обработка отсутствующих маршрутов
  • защита GeoJSON источников
  • управление асинхронными запросами
  • логирование и диагностика
  • контроль лимитов API

В результате маршрутизация становится устойчивым компонентом, а не источником нестабильности интерфейса.