ENAMETOOLONG: как одно грязное поле в базе уронило сборку статики

작성자

카테고리:

← 피드로
DEV Community · Eugene · 2026-08-16 개발(SW)

Eugene

У нас на podbor-minuta.ru около 600 страниц-подборок квартир собираются заранее в готовый HTML. Адрес каждой страницы строится из данных: город, район или метро, число комнат, цена. Например, /novostroyki/rayon/nagatino/2-komnatnye.

Однажды сборка упала с ошибкой ENAMETOOLONG – имя файла слишком длинное.

Как это вышло. Данные о квартирах мы собираем автоматически с разных сайтов. В одной записи поле “район” вместо названия района содержало целое предложение из описания, около 295 символов, что-то вроде “цены на квартиры в соседних жк начинаются от 8,9 млн рублей за однушку с отделкой”. Наш генератор страниц взял это поле и сделал из него кусок адреса. А сборщик статики (Vike) на каждый адрес создаёт папку на диске. Имя папки в файловой системе не может быть длиннее 255 байт. 295 символов кириллицы после кодирования – это заметно больше. mkdir падает, и вместе с ним падает вся сборка.

Почему нашли не сразу. Сборка идёт в Docker. Слой со сборкой статики кэшировался, и какое-то время шаг просто пропускался, ошибки не было видно. А локально сборка иногда не доходила до этого места, потому что запрос к API за данными подвисал, и страница со сломанным полем просто не попадала в набор. Ошибка вылезала только на чистой сборке в CI.

Что чинили. Две вещи.

Первое – предохранитель по длине прямо в генераторе адресов. Любой сегмент адреса длиннее разумного предела отбрасывается, страница не создаётся:

function isSafeSegment(seg: string): boolean {
  return seg.length > 0 && seg.length <= 120;
}

Enter fullscreen mode Exit fullscreen mode

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

Второе – чистка на источнике. Прятать плохие данные не хотелось, поэтому мусор отфильтровали ещё там, где район берётся из базы: значение, похожее на предложение из описания (слишком длинное, с цифрами и словами вроде “рублей”, “квартир”, “отделкой”), в подборки не попадает. Заодно это убрало десятки тонких страниц-пустышек, которые такой мусор порождал.

Что из этого забрать. В статическом сайте любое поле из базы рано или поздно становится частью имени файла. Данные, которые вы не контролируете (со скрейпинга, от пользователей), надо проверять и обрезать до того, как они превратятся в адрес или путь. И одна плохая запись не должна ронять всю сборку – лучше пропустить её, чем упасть целиком.

Сайт – podbor-minuta.ru, ежедневный мониторинг цен на новостройки Москвы.

원문에서 계속 ↗