siyuan-note/siyuan · warning · ErrBazaarRatingRateLimited
bazaarRatingRateLimited
bazaarRatingRateLimited
Error message
bazaar rating rate limited
What it means
Sentinel error ErrBazaarRatingRateLimited (kernel/model/bazaar_rating.go:60) returned by requestBazaarPackageRating when the cloud server answers an HTTP 429 Too Many Requests. It guards both getBazaarPackageRating and setBazaarPackageRating endpoints; the kernel itself additionally serializes set calls with bazaarRatingSetMu, so a 429 means the per-account/per-IP quota on the cloud side was exceeded (e.g. repeated clicks on the rating dialog), not local concurrency.
Source
Thrown at kernel/model/bazaar_rating.go:60
type bazaarRatingCloudResult[T any] struct {
Code int `json:"code"`
Msg string `json:"msg"`
Data T `json:"data"`
}
type bazaarPackageUserRatingData struct {
Rating int `json:"rating"`
}
type bazaarPackageSetRatingData struct {
Rating int `json:"rating"`
RatingAvailable *bool `json:"ratingAvailable"`
PublicRating *bazaar.PackageRating `json:"publicRating"`
Distribution []int64 `json:"distribution"`
}
// ErrBazaarRatingRateLimited 表示评分请求受到云端频率限制。
var ErrBazaarRatingRateLimited = errors.New("bazaar rating rate limited")
// GetInstalledBazaarPackageRatings 获取指定已安装包的公开评分。
func GetInstalledBazaarPackageRatings(ctx context.Context, pkgType string,
packageNames []string) (ratings map[string]*bazaar.PackageRating, eligiblePackageNames []string, err error) {
if !isValidBazaarPackageType(pkgType) {
return nil, nil, errors.New("invalid package type")
}
installedInfos, _, _, err := bazaarRatingInstalledPackageInfos(pkgType)
if nil != err {
return nil, nil, err
}
installed := make(map[string]bool, len(installedInfos))
for _, info := range installedInfos {
if "" == info.Pkg.InvalidReason {
installed[info.Pkg.Name] = true
}
}View on GitHub (pinned to afa823b6b4)
Solutions
- Match the error with errors.Is(err, model.ErrBazaarRatingRateLimited) and stop retrying immediately
- Back off (tens of seconds to minutes) before the next rating request; treat rating as an occasional user action, not polled data
- Cache rating results client-side so reopening a dialog does not re-request the cloud
Example fix
// before
rating, avail, user, err := model.SetBazaarPackageRating(ctx, pkgType, name, 4)
if err != nil {
log.Println(err) // may print repeatedly in a loop
}
// after
rating, avail, user, err := model.SetBazaarPackageRating(ctx, pkgType, name, 4)
if errors.Is(err, model.ErrBazaarRatingRateLimited) {
time.Sleep(30 * time.Second) // back off, then let the user retry once
return
} Defensive patterns
Strategy: retry
Type guard
func isRateLimited(err error) bool {
return errors.Is(err, model.ErrBazaarRatingRateLimited)
} Try / catch
err := requestRating(ctx, ...)
if errors.Is(err, model.ErrBazaarRatingRateLimited) {
// exponential backoff: wait >= 30s; abort after N attempts; surface 'try again later' to the user
} Prevention
- Cache rating responses; do not request on every dialog open
- Submit rating changes only on explicit user action, never in loops or on page load
- Honor 429 with a single delayed retry, not immediate re-sends
When it happens
Trigger: Calling model.GetBazaarPackageRating or model.SetBazaarPackageRating repeatedly in a short window: automated scripts iterating all installed packages' ratings, or a UI that re-opens the rating dialog for each star click without debounce, exhausts the cloud quota and receives 429.
Common situations: Batch scripts polling ratings; double-submitted rating forms; multiple devices on one account rating simultaneously; retry storms where each failure immediately re-triggers the request.
Related errors
- marketplace package ratings are unavailable
- invalid user rating returned by cloud server
- invalid public rating returned by cloud server
- bazaar hash not available
- marketplace package already exists
AI-assisted analysis of siyuan-note/siyuan@afa823b6b4 (2026-08-18).
Data as JSON: /api/errors/293f7b9da01593b2.
Report an issue: GitHub.