Parse error messages using JSON parser instead of regexes

This commit is contained in:
Enrico204 2020-11-15 17:41:52 +01:00 committed by Demian
parent aff4c40e36
commit 24ffa44e36
3 changed files with 32 additions and 11 deletions

View File

@ -85,6 +85,7 @@ var (
ErrFailedImageProcess = NewAPIError(400, "Bad Request: IMAGE_PROCESS_FAILED", "Image process failed")
ErrInvalidStickerSet = NewAPIError(400, "Bad Request: STICKERSET_INVALID", "Stickerset is invalid")
ErrBadPollOptions = NewAPIError(400, "Bad Request: expected an Array of String as options")
ErrGroupMigrated = NewAPIError(400, "Bad Request: group chat was upgraded to a supergroup chat")
// No rights errors
ErrNoRightsToRestrict = NewAPIError(400, "Bad Request: not enough rights to restrict/unrestrict chat member")
@ -177,6 +178,8 @@ func ErrByDescription(s string) error {
return ErrFailedImageProcess
case ErrInvalidStickerSet.ʔ():
return ErrInvalidStickerSet
case ErrGroupMigrated.ʔ():
return ErrGroupMigrated
default:
return nil
}

37
util.go
View File

@ -50,26 +50,41 @@ func wrapError(err error) error {
// In other cases it extracts API error. If error is not presented
// in errors.go, it will be prefixed with `unknown` keyword.
func extractOk(data []byte) error {
match := errorRx.FindStringSubmatch(string(data))
if match == nil || len(match) < 3 {
// Parse the error message as JSON
var tgramApiError struct {
Ok bool `json:"ok"`
ErrorCode int `json:"error_code"`
Description string `json:"description"`
Parameters map[string]interface{} `json:"parameters"`
}
err := json.Unmarshal(data, &tgramApiError)
if err != nil {
//return errors.Wrap(err, "can't parse JSON reply, the Telegram server is mibehaving")
// FIXME / TODO: in this case the error might be at HTTP level, or the content is not JSON (eg. image?)
return nil
}
desc := match[2]
err := ErrByDescription(desc)
if tgramApiError.Ok {
// No error
return nil
}
err = ErrByDescription(tgramApiError.Description)
if err == nil {
code, _ := strconv.Atoi(match[1])
switch code {
switch tgramApiError.ErrorCode {
case http.StatusTooManyRequests:
retry, _ := strconv.Atoi(match[3])
retryAfter, ok := tgramApiError.Parameters["retry_after"]
if !ok {
return NewAPIError(429, tgramApiError.Description)
}
retryAfterInt, _ := strconv.Atoi(fmt.Sprint(retryAfter))
err = FloodError{
APIError: NewAPIError(429, desc),
RetryAfter: retry,
APIError: NewAPIError(429, tgramApiError.Description),
RetryAfter: retryAfterInt,
}
default:
err = fmt.Errorf("telegram unknown: %s (%d)", desc, code)
err = fmt.Errorf("telegram unknown: %s (%d)", tgramApiError.Description, tgramApiError.ErrorCode)
}
}

View File

@ -19,6 +19,9 @@ func TestExtractOk(t *testing.T) {
APIError: NewAPIError(429, "Too Many Requests: retry after 8"),
RetryAfter: 8,
}, extractOk(data))
data = []byte(`{"ok":false,"error_code":400,"description":"Bad Request: group chat was upgraded to a supergroup chat","parameters":{"migrate_to_chat_id": -1234}}`)
assert.EqualError(t, extractOk(data), ErrGroupMigrated.Error())
}
func TestExtractMessage(t *testing.T) {