# #go
Вопрос:
У меня есть API вызовов функций для получения элементов и возврата элементов для синхронизации с другой базой данных. Я могу указать лимит возвращаемых товаров. Если лимит составляет 700, он возвращает 700 предметов. если более 700, он возвращает пустой срез.
func (d *dataBaseWriterImpl) WriteProducts() error {
username := os.Getenv("USERNAME")
password := os.Getenv("PASSWORD")
// get token
token, err := d.authService.Login(username, password)
if err != nil {
return err
}
// load products
// here the problem if count more than 700 <----
products, _ := d.scrapperService.LoadProducts(702, 1, token)
log.Printf("products count -> %d", len(products)) // gives me 0 <-----
errChan := make(chan error, 2)
var cats []models.Category
db.Conn.Model(amp;models.Category{}).Find(amp;cats)
var catIds []string
for _, cat := range cats {
catIds = append(catIds, cat.ExternalId)
}
for _, prod := range products {
if d.isValidProduct(catIds, prod.PrimaryVariant.CategoryID) {
log.Printf("update id -> %v", prod.PrimaryVariant.ID)
go d.saveOrUpdateProducts(prod.PrimaryVariant, errChan)
} else {
log.Printf("will not update id -> %v", prod.PrimaryVariant.ID)
go func() {
errChan <- nil
}()
}
}
for range products {
err := <-errChan
if err != nil {
return err
}
}
return nil
}
Я регистрирую длину элементов, прежде чем возвращать их, возвращаю фактическое значение в реализации LoadProducts.
func (s serviceImpl) LoadProducts(count uint, page uint, token string) ([]models.VariantsResult, error) {
jsonBody := []byte(fmt.Sprintf(`{"pageSize": %d, "page": %d, "sortBy": "updatedAt"}`, count, page))
body := bytes.NewBuffer(jsonBody)
// Create request
req, err := http.NewRequest("POST", fmt.Sprintf("%v/api/variantGroups/search", os.Getenv("BACKEND")), body)
if err != nil {
log.Print(err)
}
// Headers
//req.Header.Add("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:84.0) Gecko/20100101 Firefox/84.0")
req.Header.Add("Accept", "application/json, text/plain, */*")
req.Header.Add("Authorization", fmt.Sprintf("Bearer %v", token))
req.Header.Add("Content-Type", "application/json")
// Fetch Request
resp, err := s.client.Do(req)
if err != nil {
fmt.Println("Failure : ", err)
}
//[]models.Product `json:"data"`
// Read Response
type Response struct {
Results []models.VariantsResult `json:"results"`
Count int `json:"count"`
}
var response Response
err = json.NewDecoder(resp.Body).Decode(amp;response)
log.Printf("products -> %d", len(response.Results)) // gives me actual number <--
if err != nil {
return nil, err
}
return response.Results, nil
}
Комментарии:
1. Код, который вы опубликовали, является неполным.
2. @Zyl извините, я забыл поставить return
Ответ №1:
Почти наверняка вы возвращаете ошибку, но затем игнорируете ее.
Нулевой срез имеет длину и емкость 0 и не имеет базового массива. https://tour.golang.org/moretypes/12
Вы возвращаете ноль, ошибаетесь здесь:
// in LoadProducts
if err != nil {
return nil, err
}
но тогда сделайте
products, _ := d.scrapperService.LoadProducts(702, 1, token)
log.Printf("products count -> %d", len(products)) // gives me 0 <---
который должен быть
products, err := d.scrapperService.LoadProducts(702, 1, token)
if err != nil {
panic(err) // dont actually panic, but figure out what went wrong
}
log.Printf("products count -> %d", len(products)) // gives me 0 <---
Комментарии:
1. это должно быть само собой разумеется @AbanoubIstfanous, но я все равно скажу: это было бы хорошее время, чтобы выучить урок, никогда не игнорируйте ошибки в Go! В отличие от того, к чему многие люди привыкли в python, ruby, java, нет понятия вызванного исключения.