Как Slack потерял свои картинки: история об индексах и массивах

В проекте OpenClaw обнаружилась хитрая проблема с обработкой многофайловых сообщений из Slack. Когда пользователь отправлял несколько изображений одновременно, система загружала только первое, остальные просто исчезали. Звучит как обычный баг, но под капотом скрывалась классическая история о рассинхронизации данных.
Всё началось с функции resolveSlackMedia(). Она работала как конвейер: берёт сообщение, загружает файл, возвращает результат и выходит. Всё просто и понятно, пока не нужны вложения по одному. Но когда в сообщении несколько картинок — функция падала после первой, словно устав от работы. Беда была в том, что разработчики забыли основное правило: не выходи раньше времени.
Решение пришло из соседних адаптеров. Telegram, Line, Discord и iMessage давно научились собирать все загруженные файлы в массив перед возвратом. Идея простая: не возвращай результат сразу, накапливай его, а потом отдай весь пакет целиком. Именно это и сделали разработчики — завернули все пути файлов, URL-адреса и типы в соответствующие массивы MediaPaths, MediaUrls и MediaTypes.
Но тут начинались настоящие приключения. Когда внизу конвейера код пытался обработать медиа для анализа зрения (vision), подготовки sandbox или создания заметок, он ожидал, что три массива идеально синхронизированы по длине. Каждому файлу должен соответствовать его тип (application/octet-stream или более точный MIME). И вот тут обнаружилась вторая подвох: при фильтрации filter(Boolean) удалялись записи с пустыми типами, массив сжимался, индексы ломались. Файл номер два становился номером один, и система присваивала неправильный MIME-тип.
Финальный трюк — заменить фильтр на простую подстановку: если тип не определён, используй универсальный "application/octet-stream". Теперь массивы всегда совпадают по размеру, индексы совпадают, и каждый файл получает свой корректный тип, даже если система не смогла его определить с первого раза.
Это хороший пример того, как контракты между компонентами (в данном случае — обещание “три массива одинаковой длины”) могут молча ломаться, если их не охранять. Один неловкий filter() — и вся архитектура начинает пошатываться.
Факт о технологиях: Slack API исторически одна из самых сложных в обработке медиа среди мессенджеров именно потому, что поддерживает множество форматов вложений одновременно. Это требует особой внимательности при синхронизации данных.
😄 Почему Sentry не пришёл на вечеринку? Его заблокировал firewall.
Метаданные
- Branch:
- main
- Dev Joke
- Почему Sentry не пришёл на вечеринку? Его заблокировал firewall