Files
picoclaw/pkg/channels/errutil.go
T
Hoshina cc92a62812 refactor(channels): standardize Send error classification with sentinel types
All 12 channel Send methods now return proper sentinel errors (ErrNotRunning,
ErrTemporary, ErrRateLimit, ErrSendFailed) instead of plain fmt.Errorf strings,
enabling Manager's sendWithRetry classification logic to actually work.

- Add ClassifySendError/ClassifyNetError helpers in errutil.go for HTTP-based channels
- LINE/WeCom Bot/WeCom App: use ClassifySendError for HTTP status-based classification
- SDK channels (Telegram/Discord/Slack/QQ/DingTalk/Feishu): wrap errors as ErrTemporary
- WebSocket channels (OneBot/WhatsApp/MaixCam): wrap write errors as ErrTemporary
- WhatsApp: add missing IsRunning() check in Send
- WhatsApp/OneBot/MaixCam: add ctx.Done() check before entering write path
- Telegram Stop: clean up placeholders sync.Map to prevent state leaks
2026-02-24 12:10:45 +08:00

31 lines
776 B
Go

package channels
import (
"fmt"
"net/http"
)
// ClassifySendError wraps a raw error with the appropriate sentinel based on
// an HTTP status code. Channels that perform HTTP API calls should use this
// in their Send path.
func ClassifySendError(statusCode int, rawErr error) error {
switch {
case statusCode == http.StatusTooManyRequests:
return fmt.Errorf("%w: %v", ErrRateLimit, rawErr)
case statusCode >= 500:
return fmt.Errorf("%w: %v", ErrTemporary, rawErr)
case statusCode >= 400:
return fmt.Errorf("%w: %v", ErrSendFailed, rawErr)
default:
return rawErr
}
}
// ClassifyNetError wraps a network/timeout error as ErrTemporary.
func ClassifyNetError(err error) error {
if err == nil {
return nil
}
return fmt.Errorf("%w: %v", ErrTemporary, err)
}