Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added error handling for specific error codes #69

Merged
merged 12 commits into from
Apr 3, 2024

Conversation

icoder-new
Copy link
Contributor

Added error handling for specific HTTP status codes in accordance with the Telegram API specifications.

Changes:

Introduced error handling logic for HTTP status codes 403, 400, 401, 404, 409, and 429.
New error variables added for each handled status code.
Error messages now provide clearer feedback for developers.

Benefits:

Improves error handling and readability of error messages.
Simplifies debugging and development process.

@qulaz
Copy link

qulaz commented Mar 13, 2024

It would be great if the retry_after value could be retrieved from the ErrorTooManyRequests error. Like custom error type + errors.As or smth

@icoder-new
Copy link
Contributor Author

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.")
	}
}

README.md Show resolved Hide resolved
raw_request.go Show resolved Hide resolved
raw_request.go Outdated Show resolved Hide resolved
raw_request.go Outdated Show resolved Hide resolved
@negasus negasus merged commit e65d48b into go-telegram:main Apr 3, 2024
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants