DEV Community

Eugene
Eugene

Posted on

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

У нас на 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, ежедневный мониторинг цен на новостройки Москвы.

Top comments (0)