harden deezer auth errors and mixed playlist preflight

This commit is contained in:
2026-04-21 12:19:23 +02:00
parent 1246a24749
commit 654bed17e2
4 changed files with 142 additions and 22 deletions

View File

@@ -203,6 +203,12 @@ func (c *Client) GetMetadata(ctx context.Context, item, mediaType string) (map[s
resp["tracks"] = map[string]any{"items": items}
return resp, nil
case "artist":
name := strings.TrimSpace(item)
if artistMeta, artistErr := c.apiGet(ctx, "/artist/"+item, nil); artistErr == nil {
if n := strings.TrimSpace(stringFromAny(artistMeta["name"])); n != "" {
name = n
}
}
resp, err := c.getArtistAlbums(ctx, item)
if err != nil {
return nil, err
@@ -218,7 +224,7 @@ func (c *Client) GetMetadata(ctx context.Context, item, mediaType string) (map[s
albums = append(albums, itm)
}
}
return map[string]any{"name": "", "albums": map[string]any{"items": albums}}, nil
return map[string]any{"name": name, "albums": map[string]any{"items": albums}}, nil
default:
return nil, fmt.Errorf("unsupported deezer media type: %s", mediaType)
}
@@ -727,10 +733,20 @@ func (c *Client) mobileAuth(ctx context.Context) (string, error) {
if err != nil {
return "", err
}
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
return "", fmt.Errorf("mobile_auth failed: status=%d body=%s", resp.StatusCode, string(raw))
}
out := map[string]any{}
if err = json.Unmarshal(raw, &out); err != nil {
return "", err
}
if errObj, ok := out["error"].(map[string]any); ok && len(errObj) > 0 {
msg := firstNonEmpty(stringFromAny(errObj["message"]), stringFromAny(errObj["type"]))
if msg == "" {
msg = "mobile_auth returned an error"
}
return "", errors.New(msg)
}
token := findStringByKey(nestedMap(out, "results"), "TOKEN")
if token == "" {
return "", errors.New("mobile_auth returned empty token")
@@ -764,10 +780,20 @@ func (c *Client) apiCheckToken(ctx context.Context, authToken string) (string, e
if err != nil {
return "", err
}
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
return "", fmt.Errorf("api_checkToken failed: status=%d body=%s", resp.StatusCode, string(raw))
}
out := map[string]any{}
if err = json.Unmarshal(raw, &out); err != nil {
return "", err
}
if errObj, ok := out["error"].(map[string]any); ok && len(errObj) > 0 {
msg := firstNonEmpty(stringFromAny(errObj["message"]), stringFromAny(errObj["type"]))
if msg == "" {
msg = "api_checkToken returned an error"
}
return "", errors.New(msg)
}
sid := strings.TrimSpace(stringFromAny(out["results"]))
if sid == "" {
return "", errors.New("api_checkToken returned empty sid")
@@ -861,10 +887,20 @@ func (c *Client) refreshJWT(ctx context.Context) error {
}
defer func() { _ = resp.Body.Close() }()
raw, _ := io.ReadAll(resp.Body)
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
return fmt.Errorf("jwt refresh failed: status=%d body=%s", resp.StatusCode, string(raw))
}
out := map[string]any{}
if json.Unmarshal(raw, &out) != nil {
return errors.New("invalid jwt refresh response")
}
if errObj, ok := out["error"].(map[string]any); ok && len(errObj) > 0 {
msg := firstNonEmpty(stringFromAny(errObj["message"]), stringFromAny(errObj["type"]))
if msg == "" {
msg = "jwt refresh returned an error"
}
return errors.New(msg)
}
if jwt := strings.TrimSpace(stringFromAny(out["jwt"])); jwt != "" {
c.jwt = jwt
}
@@ -905,10 +941,23 @@ func (c *Client) refreshLicenseFromPipe(ctx context.Context) error {
}
defer func() { _ = resp.Body.Close() }()
raw, _ := io.ReadAll(resp.Body)
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
return fmt.Errorf("pipe license refresh failed: status=%d body=%s", resp.StatusCode, string(raw))
}
out := map[string]any{}
if json.Unmarshal(raw, &out) != nil {
return errors.New("invalid pipe response")
}
if errs, ok := out["errors"].([]any); ok && len(errs) > 0 {
msg := ""
if em, ok := errs[0].(map[string]any); ok {
msg = strings.TrimSpace(stringFromAny(em["message"]))
}
if msg == "" {
msg = "pipe response returned graphql error"
}
return errors.New(msg)
}
token := findStringByKey(out, "token")
if token == "" {
return errors.New("pipe response missing license token")