diff --git a/SimklFunctions.go b/SimklFunctions.go index 156cf4f..19261b2 100644 --- a/SimklFunctions.go +++ b/SimklFunctions.go @@ -14,16 +14,24 @@ import ( var SimklWatchList SimklWatchListType -func SimklHelper(method string, url string, body interface{}) json.RawMessage { - reader, _ := json.Marshal(body) +func SimklHelper(method string, url string, body interface{}) (json.RawMessage, error) { + reader, err := json.Marshal(body) + if err != nil { + return nil, fmt.Errorf("failed to marshal body: %w", err) + } + var req *http.Request client := &http.Client{} if body != nil { - req, _ = http.NewRequest(method, url, bytes.NewBuffer(reader)) + req, err = http.NewRequest(method, url, bytes.NewBuffer(reader)) } else { - req, _ = http.NewRequest(method, url, nil) + req, err = http.NewRequest(method, url, nil) + } + + if err != nil { + return nil, fmt.Errorf("failed to create request: %w", err) } req.Header.Add("Content-Type", "application/json") @@ -32,41 +40,45 @@ func SimklHelper(method string, url string, body interface{}) json.RawMessage { resp, err := client.Do(req) if err != nil { - fmt.Println("Errored when sending request to the server") - message, _ := json.Marshal(struct { - Message string `json:"message"` - }{ - Message: "Errored when sending request to the server" + err.Error(), - }) - - return message + return nil, fmt.Errorf("network error: %w", err) } defer resp.Body.Close() - respBody, _ := io.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) - return respBody + if err != nil { + return nil, fmt.Errorf("failed to read response: %w", err) + } + if resp.StatusCode < 200 || resp.StatusCode >= 300 { + return respBody, fmt.Errorf("API returned status: %d", resp.StatusCode) + } + return respBody, nil } -func (a *App) SimklGetUserWatchlist() SimklWatchListType { +func (a *App) SimklGetUserWatchlist() (SimklWatchListType, error) { method := "GET" url := "https://api.simkl.com/sync/all-items/anime" - respBody := SimklHelper(method, url, nil) + respBody, err := SimklHelper(method, url, nil) + + if err != nil { + return SimklWatchListType{}, fmt.Errorf("failed to get Simkl watchlist: %w", err) + } var errCheck struct { Error string `json:"error"` Message string `json:"message"` } - err := json.Unmarshal(respBody, &errCheck) + err = json.Unmarshal(respBody, &errCheck) if err != nil { log.Printf("Failed at unmarshal, %s\n", err) + return SimklWatchListType{}, fmt.Errorf("failed to parse error response: %w", err) } if errCheck.Error != "" { a.LogoutSimkl() - return SimklWatchListType{} + return SimklWatchListType{}, fmt.Errorf("Simkl API error: %s", errCheck.Message) } var watchlist SimklWatchListType @@ -74,14 +86,15 @@ func (a *App) SimklGetUserWatchlist() SimklWatchListType { err = json.Unmarshal(respBody, &watchlist) if err != nil { log.Printf("Failed at unmarshal, %s\n", err) + return SimklWatchListType{}, fmt.Errorf("failed to parse watchlist: %w", err) } SimklWatchList = watchlist - return watchlist + return watchlist, nil } -func (a *App) SimklSyncEpisodes(anime SimklAnime, progress int) SimklAnime { +func (a *App) SimklSyncEpisodes(anime SimklAnime, progress int) (SimklAnime, error) { var episodes []Episode var url string var shows []SimklPostShow @@ -112,13 +125,19 @@ func (a *App) SimklSyncEpisodes(anime SimklAnime, progress int) SimklAnime { simklSync := SimklSyncHistoryType{shows} - respBody := SimklHelper("POST", url, simklSync) + respBody, err := SimklHelper("POST", url, simklSync) + + if err != nil { + log.Printf("Failed to sync episodes: %s\n", err) + return anime, fmt.Errorf("failed to sync episodes: %w", err) + } var success interface{} - err := json.Unmarshal(respBody, &success) + err = json.Unmarshal(respBody, &success) if err != nil { log.Printf("Failed at unmarshal, %s\n", err) + return anime, fmt.Errorf("failed to parse response: %w", err) } for i, simklAnime := range SimklWatchList.Anime { @@ -131,10 +150,10 @@ func (a *App) SimklSyncEpisodes(anime SimklAnime, progress int) SimklAnime { WatchListUpdate(anime) - return anime + return anime, nil } -func (a *App) SimklSyncRating(anime SimklAnime, rating int) SimklAnime { +func (a *App) SimklSyncRating(anime SimklAnime, rating int) (SimklAnime, error) { var url string showWithRating := ShowWithRating{ Title: anime.Show.Title, @@ -169,13 +188,17 @@ func (a *App) SimklSyncRating(anime SimklAnime, rating int) SimklAnime { Shows []interface{} `json:"shows" ts_type:"shows"` }{shows} - respBody := SimklHelper("POST", url, simklSync) - + respBody, err := SimklHelper("POST", url, simklSync) + if err != nil { + log.Printf("Failed to sync rating: %s\n", err) + return anime, fmt.Errorf("failed to sync rating: %w", err) + } var success interface{} - err := json.Unmarshal(respBody, &success) + err = json.Unmarshal(respBody, &success) if err != nil { log.Printf("Failed at unmarshal, %s\n", err) + return anime, fmt.Errorf("failed to parse response: %w", err) } for i, simklAnime := range SimklWatchList.Anime { @@ -188,10 +211,10 @@ func (a *App) SimklSyncRating(anime SimklAnime, rating int) SimklAnime { WatchListUpdate(anime) - return anime + return anime, nil } -func (a *App) SimklSyncStatus(anime SimklAnime, status string) SimklAnime { +func (a *App) SimklSyncStatus(anime SimklAnime, status string) (SimklAnime, error) { url := "https://api.simkl.com/sync/add-to-list" show := SimklShowStatus{ Title: anime.Show.Title, @@ -211,13 +234,17 @@ func (a *App) SimklSyncStatus(anime SimklAnime, status string) SimklAnime { Shows []SimklShowStatus `json:"shows" ts_type:"shows"` }{shows} - respBody := SimklHelper("POST", url, simklSync) - + respBody, err := SimklHelper("POST", url, simklSync) + if err != nil { + log.Printf("Failed to sync status: %s\n", err) + return anime, fmt.Errorf("failed to sync status: %w", err) + } var success interface{} - err := json.Unmarshal(respBody, &success) + err = json.Unmarshal(respBody, &success) if err != nil { log.Printf("Failed at unmarshal, %s\n", err) + return anime, fmt.Errorf("failed to parse response: %w", err) } for i, simklAnime := range SimklWatchList.Anime { @@ -230,15 +257,20 @@ func (a *App) SimklSyncStatus(anime SimklAnime, status string) SimklAnime { WatchListUpdate(anime) - return anime + return anime, nil } -func (a *App) SimklSearch(aniListAnime MediaList) SimklAnime { +func (a *App) SimklSearch(aniListAnime MediaList) (SimklAnime, error) { var result SimklAnime if reflect.DeepEqual(SimklWatchList, SimklWatchListType{}) { fmt.Println("Watchlist empty. Calling...") - SimklWatchList = a.SimklGetUserWatchlist() + watchlist, err := a.SimklGetUserWatchlist() + if err != nil { + log.Printf("Failed to get watchlist: %s\n", err) + return result, fmt.Errorf("failed to load watchlist for search: %w", err) + } + SimklWatchList = watchlist } for _, anime := range SimklWatchList.Anime { @@ -255,22 +287,30 @@ func (a *App) SimklSearch(aniListAnime MediaList) SimklAnime { var anime SimklSearchType url := "https://api.simkl.com/search/id?anilist=" + strconv.Itoa(aniListAnime.Media.ID) - respBody := SimklHelper("GET", url, nil) - - err := json.Unmarshal(respBody, &anime) + respBody, err := SimklHelper("GET", url, nil) + if err != nil { + log.Printf("Failed to search Simkl: %s\n", err) + return result, fmt.Errorf("failed to search Simkl by AniList ID: %w", err) + } + err = json.Unmarshal(respBody, &anime) if len(anime) == 0 { url = "https://api.simkl.com/search/id?mal=" + strconv.Itoa(aniListAnime.Media.IDMal) - respBody = SimklHelper("GET", url, nil) + respBody, err = SimklHelper("GET", url, nil) + if err != nil { + log.Printf("Failed to search Simkl by MAL ID: %s\n", err) + return result, fmt.Errorf("failed to search by MAL ID: %w", err) + } err = json.Unmarshal(respBody, &anime) } if err != nil { log.Printf("Failed at unmarshal, %s\n", err) + return result, fmt.Errorf("failed to parse search results: %w", err) } if len(anime) == 0 { - return result + return result, nil } for _, watchListAnime := range SimklWatchList.Anime { @@ -288,10 +328,10 @@ func (a *App) SimklSearch(aniListAnime MediaList) SimklAnime { } } - return result + return result, nil } -func (a *App) SimklSyncRemove(anime SimklAnime) bool { +func (a *App) SimklSyncRemove(anime SimklAnime) (bool, error) { url := "https://api.simkl.com/sync/history/remove" var showArray []SimklShowStatus @@ -312,25 +352,28 @@ func (a *App) SimklSyncRemove(anime SimklAnime) bool { Shows: showArray, } - respBody := SimklHelper("POST", url, show) + respBody, err := SimklHelper("POST", url, show) + if err != nil { + log.Printf("Failed to sync remove: %s\n", err) + return false, fmt.Errorf("failed to sync remove: %w", err) + } var success SimklDeleteType - - err := json.Unmarshal(respBody, &success) + err = json.Unmarshal(respBody, &success) if err != nil { log.Printf("Failed at unmarshal, %s\n", err) + return false, fmt.Errorf("failed to parse response: %w", err) } - if success.Deleted.Shows >= 1 { for i, simklAnime := range SimklWatchList.Anime { if simklAnime.Show.Ids.Simkl == anime.Show.Ids.Simkl { SimklWatchList.Anime = slices.Delete(SimklWatchList.Anime, i, i+1) } } - return true - } else { - return false + return true, nil } + + return false, fmt.Errorf("no shows were deleted") } func WatchListUpdate(anime SimklAnime) { diff --git a/SimklUserFunctions.go b/SimklUserFunctions.go index bd787db..51b4333 100644 --- a/SimklUserFunctions.go +++ b/SimklUserFunctions.go @@ -116,7 +116,7 @@ func (a *App) handleSimklCallback(wg *sync.WaitGroup) { go func() { defer wg.Done() if err := srv.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) { - log.Fatalf("listen: %s\n", err) + log.Printf("Server error: %s\n", err) } fmt.Println("Shutting down...") }() @@ -138,7 +138,8 @@ func getSimklAuthorizationToken(content string) SimklJWT { } jsonData, err := json.Marshal(data) if err != nil { - log.Fatal(err) + log.Printf("Failed to marshal data: %s\n", err) + return SimklJWT{} } response, err := http.NewRequest("POST", "https://api.simkl.com/oauth/token", bytes.NewBuffer(jsonData))