awesome-cli/internal/service/coffee_service.go

97 lines
2.4 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package service
import (
"errors"
"fmt"
"awesome_cli/internal/client"
libErr "code.linberg.su/linberg/awesome-back/pkg/errors"
)
type Coffee struct {
ID int `json:"id"`
Name string `json:"name"`
Description string `json:"description"`
Price float64 `json:"price"`
Size string `json:"size"`
}
type CoffeeService struct {
apiClient *client.APIClient
}
func NewCoffeeService(apiClient *client.APIClient) *CoffeeService {
return &CoffeeService{
apiClient: apiClient,
}
}
func (s *CoffeeService) GetAllCoffees() ([]Coffee, error) {
var coffees []Coffee
err := s.apiClient.Get("/api/v1/coffees", &coffees)
if err != nil {
return nil, libErr.Wrap(err, "failed to fetch coffees")
}
return coffees, nil
}
func (s *CoffeeService) GetCoffeeByID(id int) (*Coffee, error) {
if id <= 0 {
return nil, libErr.NewInvalidError("coffee ID must be positive")
}
var coffee Coffee
path := fmt.Sprintf("/api/v1/coffees/%d", id)
err := s.apiClient.Get(path, &coffee)
if err != nil {
// Демонстрация использования errors.Is и errors.As
if libErr.IsNotFound(err) {
return nil, libErr.NewNotFoundError(fmt.Sprintf("coffee with ID %d not found", id))
}
return nil, libErr.Wrapf(err, "failed to fetch coffee with ID %d", id)
}
return &coffee, nil
}
// GetCoffeeByIDWithRetry демонстрирует сложную обработку ошибок с retry логикой
func (s *CoffeeService) GetCoffeeByIDWithRetry(id int, maxRetries int) (*Coffee, error) {
var lastErr error
for attempt := 0; attempt <= maxRetries; attempt++ {
coffee, err := s.GetCoffeeByID(id)
if err == nil {
return coffee, nil
}
lastErr = err
// Проверяем тип ошибки для принятия решения о retry
if libErr.IsNetworkError(err) {
// Network errors - можно retry
continue
}
if libErr.IsNotFound(err) || libErr.IsInvalid(err) {
// Client errors - не retry
break
}
// Для других ошибок можно добавить дополнительную логику
var appErr *libErr.AppError
if errors.As(err, &appErr) {
switch appErr.Type {
case libErr.ErrorTypeInternal:
// Server errors - можно retry
continue
default:
// Другие ошибки - не retry
break
}
}
}
return nil, libErr.Wrapf(lastErr, "failed after %d attempts", maxRetries+1)
}