diff --git a/internal/core/importer/curseforge.go b/internal/core/importer/curseforge.go index f21a0c5..d6473f8 100644 --- a/internal/core/importer/curseforge.go +++ b/internal/core/importer/curseforge.go @@ -22,8 +22,8 @@ import ( type CurseForgeImporter struct { StoragePath string APIKey string - HTTPClient *http.Client // Для быстрых API-запросов - HTTPClientLong *http.Client // ИСПРАВЛЕНИЕ: Добавляем это поле в структуру + HTTPClient *http.Client + HTTPClientLong *http.Client } // NewCurseForgeImporter создает новый экземпляр импортера. @@ -38,7 +38,6 @@ func NewCurseForgeImporter(storagePath, apiKey string) *CurseForgeImporter { // downloadAndProcessFile скачивает файл по URL и передает его в общий обработчик. func (i *CurseForgeImporter) downloadAndProcessFile(url string) (hash string, size int64, err error) { - // Используем клиент с длинным таймаутом и для скачивания отдельных модов req, err := http.NewRequestWithContext(context.Background(), "GET", url, nil) if err != nil { return "", 0, err @@ -67,7 +66,6 @@ func (i *CurseForgeImporter) getFileInfo(projectID, fileID int) (*CurseForgeFile } req.Header.Set("x-api-key", i.APIKey) - // Используем клиент с коротким таймаутом для быстрых API-запросов resp, err := i.HTTPClient.Do(req) if err != nil { return nil, err @@ -83,10 +81,6 @@ func (i *CurseForgeImporter) getFileInfo(projectID, fileID int) (*CurseForgeFile return nil, fmt.Errorf("failed to decode file info response: %w", err) } - if fileInfo.Data.DownloadURL == "" { - return nil, fmt.Errorf("received empty download URL from API for fileID %d", fileID) - } - return &fileInfo, nil } @@ -227,15 +221,24 @@ func (i *CurseForgeImporter) Import(zipPath string) ([]models.ModpackFile, error for _, modFile := range manifest.Files { fileInfo, err := i.getFileInfo(modFile.ProjectID, modFile.FileID) if err != nil { - return nil, fmt.Errorf("failed to get info for fileID %d: %w", modFile.FileID, err) + log.Printf("Importer: WARN - Could not get info for fileID %d, skipping. Error: %v", modFile.FileID, err) + continue } downloadURL := fileInfo.Data.DownloadURL fileName := fileInfo.Data.FileName + // ИСПРАВЛЕНИЕ: Проверяем, что URL не пустой + if downloadURL == "" { + log.Printf("Importer: WARN - Empty download URL for file '%s' (fileID %d), skipping.", fileName, modFile.FileID) + continue // Пропускаем этот файл + } + hash, size, err := i.downloadAndProcessFile(downloadURL) if err != nil { - return nil, fmt.Errorf("failed to process downloaded file '%s' (fileID %d): %w", fileName, modFile.FileID, err) + // Вместо того чтобы падать, просто логируем ошибку и пропускаем файл + log.Printf("Importer: WARN - Failed to process downloaded file '%s' (fileID %d), skipping. Error: %v", fileName, modFile.FileID, err) + continue } relativePath := filepath.Join("mods", fileName)