npmlibpublish 429: Слишком много запросов при использовании функции публикации

Вопросы и ответы

Я пытаюсь автоматически опубликовать свой пакет в npm, используя JavaScript SDK npmlibpublish. Вот мой код:

const path = "dist";
    const manifest = await pacote.manifest(path);
    const tarData = await pacote.tarball(path);

    // @ts-ignore
    await publish(manifest, tarData, {
      npmVersion: `universal-fs@${currentVersion}`,
      token: process.env.NPM_TOKEN,
      defaultTag: baseBranch === "main" ? "latest" : "canary",
    });

Этот код будет запущен в CI. Все переменные окружения корректны, а также manifest и tarball. Однако, когда я выполняю код, я получаю ошибку:

429 Слишком много запросов - PUT https://registry.npmjs.org/dist

{
  headers: [Object: null prototype] {
    date: [ 'Вт, 17 Сен 2024 01:46:11 GMT' ],
    'content-type': [ 'text/html; charset=UTF-8' ],
    'content-length': [ '5399' ],
    connection: [ 'keep-alive' ],
    'retry-after': [ '3600' ],
    'x-frame-options': [ 'SAMEORIGIN' ],
    'referrer-policy': [ 'same-origin' ],
    'cache-control': [
      'private, max-age=0, no-store, no-cache, must-revalidate, post-check=0, pre-check=0'
    ],
    expires: [ 'Чт, 01 Янв 1970 00:00:01 GMT' ],
    vary: [ 'Accept-Encoding' ],
    server: [ 'cloudflare' ],
    'cf-ray': [ '8c456bccdd722b8e-LAX' ],
    'x-fetch-attempts': [ '1' ]
  },
  statusCode: 429,
  code: 'E429',
  method: 'PUT',
  uri: 'https://registry.npmjs.org/dist',
  body: Buffer(5399) [Uint8Array] [
     60,  33,  68,  79,  67,  84,  89,  80,  69,  32, 104, 116,
    109, 108,  62,  10,  60,  33,  45,  45,  91, 105, 102,  32,
    108, 116,  73,  69,  32,  55,  93,  62,  32,  60, 104,
    116, 109, 108,  32,  99, 108,  97, 115, 115,  61, 34, 110,
    111,  45, 106, 115,  32, 105, 101,  54,  32, 111, 108, 100,
    105, 101, 34,  32, 108,  97, 110, 103,  61, 34, 101, 110,
     45,  85,  83, 34,  62,  32,  60,  33,  91, 101, 110, 100,
    105, 102,  93, 45,  45,  62,  10,  60,  33,  45,  45,  91,
    105, 102,  32,  73,
    ... 5299 more items
  ],
  pkgid: '[email protected]'
}

Что мне показалось странным, так это то, что он пытался опубликовать пакет с названием dist, как видно из pkgid: '[email protected]'. Однако мой пакет называется universal-fs, и я публикую его из директории dist.

У меня включена двухфакторная аутентификация на моем аккаунте. name также определено в моем package.json. Почему он пытается опубликовать по адресу [email protected] и почему статус-код 429? Как я могу это исправить?

Ответ

Проблема, с которой вы столкнулись, связана с ошибкой 429 (Слишком много запросов) при попытке публикации пакета в NPM. Также вы заметили, что ваш пакет пытается опубликоваться под именем dist, что не соответствует ожидаемому имени вашего пакета (universal-fs). Давайте разберем причины и предложим решения.

Причины проблемы

  1. Ошибка 429 (Слишком много запросов):

    • Эта ошибка возникает, когда вы превышаете лимиты на отправку запросов к API NPM. Обычно NPM накладывает ограничения на количество запросов, чтобы предотвратить злоупотребления и обеспечить стабильность сервиса. В вашем случае, судя по сообщениям, NPM сообщает, что вы отправили слишком много запросов за короткий промежуток времени, и советует подождать (в данном случае 3600 секунд, или 1 час).
  2. Попытка публикации под именем dist:
    • Судя по вашему коду, проблема может возникать из-за того, что функция publish неправильно считывает name из вашего манифеста. Убедитесь, что в вашем package.json правильно указано имя пакета и что оно соответствует тому, что вы ожидаете (в данном случае, universal-fs).

Возможные решения

  1. Обработка ошибки 429:

    • Вы можете реализовать стратегию повторной попытки (retry) для обработки ошибок 429. Это можно сделать, например, с помощью временной задержки между повторными попытками.
    • Пример кода с обработкой:

      const publishWithRetry = async (manifest, tarData) => {
      const maxRetries = 5;
      let attempt = 0;
      
      while (attempt < maxRetries) {
       try {
         await publish(manifest, tarData, {
           npmVersion: `universal-fs@${currentVersion}`,
           token: process.env.NPM_TOKEN,
           defaultTag: baseBranch === "main" ? "latest" : "canary",
         });
         return; // Успех, выходим из функции
       } catch (error) {
         if (error.code === 'E429') {
           attempt++;
           const retryAfter = error.headers['retry-after'] ? parseInt(error.headers['retry-after']) * 1000 : 1000; // по умолчанию 1 секунда
           console.log(`Attempt ${attempt} failed. Retrying in ${retryAfter / 1000} seconds...`);
           await new Promise(resolve => setTimeout(resolve, retryAfter)); // Ожидание перед повторной попыткой
         } else {
           throw error; // Если ошибка не 429, выбрасываем ее
         }
       }
      }
      throw new Error('Maximum retries exceeded');
      };
  2. Проверьте ваш package.json:

    • Убедитесь, что имя вашего пакета в package.json правильно указано. Например:

      {
      "name": "universal-fs",
      "version": "1.0.0",
      ...
      }
  3. Долгосрочные решения:
    • Оцените частоту ваших публикаций. Возможно, имеет смысл добавить дополнительную логику, чтобы избежать частых публикаций из CI/CD.
    • Рассмотрите возможность использования npm publish –dry-run перед фактической публикацией. Это поможет убедиться, что вы пытаетесь публиковать правильный пакет и не превышаете лимиты.

Заключение

Ваша ошибка 429 скорее всего вызвана частыми попытками публикации. Реализация стратегии повторной попытки и коррекция имени пакета в вашем package.json помогут решить вашу проблему. Убедитесь также, что вы не превышаете лимиты запросов к NPM, чтобы избежать дальнейших ошибок.

Оцените материал
Добавить комментарий

Капча загружается...