Closed icoder-new closed 3 months ago
It would be great if the retry_after
value could be retrieved from the ErrorTooManyRequests
error. Like custom error type + errors.As
or smth
Added parameters
field to API response with retry_after
information for rate limiting. Implemented error handling for HTTP status code 429 (Too Many Requests) in the rawRequest
function, extracting the retry_after
value for proper handling of rate-limiting scenarios.
Here is a brief example demonstrating how TooManyRequestsError
works.
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"strings"
)
var (
ErrorTooManyRequests = fmt.Errorf("too many requests")
)
type TooManyRequestsError struct {
Message string
RetryAfter int
}
func (e *TooManyRequestsError) Error() string {
return fmt.Sprintf("%s: retry_after %d", e.Message, e.RetryAfter)
}
func IsTooManyRequestsError(err error) bool {
_, ok := err.(*TooManyRequestsError)
return ok
}
type apiResponse struct {
OK bool `json:"ok"`
Result json.RawMessage `json:"result,omitempty"`
Description string `json:"description,omitempty"`
ErrorCode int `json:"error_code,omitempty"`
Parameters struct {
RetryAfter int `json:"retry_after"`
} `json:"parameters,omitempty"`
}
func rawRequest() error {
mockResponse := `{
"ok": false,
"error_code": 429,
"description": "Too Many Requests: retry after 35",
"parameters": {
"retry_after": 35
}
}`
body := strings.NewReader(mockResponse)
// Mocking an HTTP response
r := &http.Response{
StatusCode: http.StatusTooManyRequests,
Body: io.NopCloser(body),
}
// Parse API response
var apiResp apiResponse
errDecode := json.NewDecoder(r.Body).Decode(&apiResp)
if errDecode != nil {
return fmt.Errorf("error decoding API response: %w", errDecode)
}
if apiResp.ErrorCode == 429 {
err := &TooManyRequestsError{
Message: fmt.Sprintf("%w, %s", ErrorTooManyRequests, apiResp.Description),
RetryAfter: apiResp.Parameters.RetryAfter,
}
return err
}
return nil
}
func main() {
err := rawRequest()
if err != nil {
if IsTooManyRequestsError(err) {
fmt.Println("Received TooManyRequestsError with retry_after:", err.(*TooManyRequestsError).RetryAfter)
} else {
fmt.Println("Received error:", err)
}
} else {
fmt.Println("No error received.")
}
}
Added error handling for specific HTTP status codes in accordance with the Telegram API specifications.
Changes:
Benefits: