Refactor code, fix code style issues

pull/269/head
unknown 4 years ago
parent 361c4399f8
commit ce43c6a8a2

102
api.go

@ -22,7 +22,7 @@ func (b *Bot) Raw(method string, payload interface{}) ([]byte, error) {
var buf bytes.Buffer
if err := json.NewEncoder(&buf).Encode(payload); err != nil {
return []byte{}, wrapSystem(err)
return []byte{}, wrapError(err)
}
resp, err := b.client.Post(url, "application/json", &buf)
@ -32,87 +32,23 @@ func (b *Bot) Raw(method string, payload interface{}) ([]byte, error) {
resp.Close = true
defer resp.Body.Close()
json, err := ioutil.ReadAll(resp.Body)
data := apiErrorRx.FindStringSubmatch(string(json))
data, err := ioutil.ReadAll(resp.Body)
if err != nil {
return []byte{}, wrapSystem(err)
return []byte{}, wrapError(err)
}
if data == nil {
return json, nil
match := errorRx.FindStringSubmatch(string(data))
if match == nil || len(match) < 3 {
return data, nil
}
description := data[2]
code, _ := strconv.Atoi(data[0])
switch description {
case ErrUnauthorized.ʔ():
err = ErrUnauthorized
case ErrToForwardNotFound.ʔ():
err = ErrToForwardNotFound
case ErrToReplyNotFound.ʔ():
err = ErrToReplyNotFound
case ErrMessageTooLong.ʔ():
err = ErrMessageTooLong
case ErrBlockedByUsr.ʔ():
err = ErrBlockedByUsr
case ErrToDeleteNotFound.ʔ():
err = ErrToDeleteNotFound
case ErrEmptyMessage.ʔ():
err = ErrEmptyMessage
case ErrEmptyText.ʔ():
err = ErrEmptyText
case ErrEmptyChatID.ʔ():
err = ErrEmptyChatID
case ErrNotFoundChat.ʔ():
err = ErrNotFoundChat
case ErrMessageNotModified.ʔ():
err = ErrMessageNotModified
case ErrNoRightsToRestrict.ʔ():
err = ErrNoRightsToRestrict
case ErrNoRightsToSendMsg.ʔ():
err = ErrNoRightsToSendMsg
case ErrNoRightsToSendPhoto.ʔ():
err = ErrNoRightsToSendPhoto
case ErrNoRightsToSendStickers.ʔ():
err = ErrNoRightsToSendStickers
case ErrNoRightsToSendGifs.ʔ():
err = ErrNoRightsToSendGifs
case ErrNoRightsToDelete.ʔ():
err = ErrNoRightsToDelete
case ErrKickingChatOwner.ʔ():
err = ErrKickingChatOwner
case ErrInteractKickedG.ʔ():
err = ErrKickingChatOwner
case ErrInteractKickedSprG.ʔ():
err = ErrInteractKickedSprG
case ErrWrongTypeOfContent.ʔ():
err = ErrWrongTypeOfContent
case ErrCantGetHTTPurlContent.ʔ():
err = ErrCantGetHTTPurlContent
case ErrWrongRemoteFileID.ʔ():
err = ErrWrongRemoteFileID
case ErrFileIdTooShort.ʔ():
err = ErrFileIdTooShort
case ErrWrongRemoteFileIDsymbol.ʔ():
err = ErrWrongRemoteFileIDsymbol
case ErrWrongFileIdentifier.ʔ():
err = ErrWrongFileIdentifier
case ErrTooLarge.ʔ():
err = ErrTooLarge
case ErrWrongPadding.ʔ():
err = ErrWrongPadding
case ErrImageProcess.ʔ():
err = ErrImageProcess
case ErrWrongStickerpack.ʔ():
err = ErrWrongStickerpack
default:
err = fmt.Errorf("unknown api error: %s (%d)", description, code)
desc := match[2]
err = errByDescription(desc)
if err == nil {
code, _ := strconv.Atoi(match[1])
err = fmt.Errorf("unknown api error: %s (%d)", desc, code)
}
if err != nil {
return []byte{}, err
}
return json, nil
return data, err
}
func addFileToWriter(writer *multipart.Writer,
@ -170,24 +106,24 @@ func (b *Bot) sendFiles(method string, files map[string]File,
for field, file := range rawFiles {
if err := addFileToWriter(writer, params["file_name"], field, file); err != nil {
return nil, wrapSystem(err)
return nil, wrapError(err)
}
}
for field, value := range params {
if err := writer.WriteField(field, value); err != nil {
return nil, wrapSystem(err)
return nil, wrapError(err)
}
}
if err := writer.Close(); err != nil {
return nil, wrapSystem(err)
return nil, wrapError(err)
}
url := b.URL + "/bot" + b.Token + "/" + method
req, err := http.NewRequest("POST", url, body)
if err != nil {
return nil, wrapSystem(err)
return nil, wrapError(err)
}
req.Header.Add("Content-Type", writer.FormDataContentType())
@ -202,12 +138,12 @@ func (b *Bot) sendFiles(method string, files map[string]File,
return nil, errors.New("api error: internal server error")
}
json, err := ioutil.ReadAll(resp.Body)
data, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, wrapSystem(err)
return nil, wrapError(err)
}
return json, nil
return data, nil
}
func (b *Bot) sendObject(f *File, what string, params map[string]string, files map[string]File) (*Message, error) {

@ -147,7 +147,7 @@ func (b *Bot) Handle(endpoint interface{}, handler interface{}) {
}
var (
cmdRx = regexp.MustCompile(`^(\/\w+)(@(\w+))?(\s|$)(.+)?`)
cmdRx = regexp.MustCompile(`^(/\w+)(@(\w+))?(\s|$)(.+)?`)
cbackRx = regexp.MustCompile(`^\f(\w+)(\|(.+))?$`)
)
@ -1105,19 +1105,19 @@ func (b *Bot) FileByID(fileID string) (File, error) {
func (b *Bot) Download(file *File, localFilename string) error {
reader, err := b.GetFile(file)
if err != nil {
return wrapSystem(err)
return wrapError(err)
}
defer reader.Close()
out, err := os.Create(localFilename)
if err != nil {
return wrapSystem(err)
return wrapError(err)
}
defer out.Close()
_, err = io.Copy(out, reader)
if err != nil {
return wrapSystem(err)
return wrapError(err)
}
file.FileLocal = localFilename
@ -1135,7 +1135,7 @@ func (b *Bot) GetFile(file *File) (io.ReadCloser, error) {
req, err := http.NewRequest("GET", b.URL+"/file/bot"+b.Token+"/"+f.FilePath, nil)
if err != nil {
return nil, wrapSystem(err)
return nil, wrapError(err)
}
resp, err := b.client.Do(req)
@ -1374,7 +1374,7 @@ func (b *Bot) ChatByID(id string) (*Chat, error) {
}
if resp.Result.Type == ChatChannel && resp.Result.Username == "" {
//Channel is Private
// Channel is Private
resp.Result.Type = ChatChannelPrivate
}

@ -6,82 +6,151 @@ import (
"strings"
)
type ApiError struct {
type APIError struct {
Code int
Description string
message string
Message string
}
func (err *ApiError) ʔ() string {
// ʔ returns description of error.
// A tiny shortcut to make code clearier.
func (err *APIError) ʔ() string {
return err.Description
}
func badRequest(description ...string) *ApiError {
if len(description) == 1 {
return &ApiError{400, description[0], ""}
}
return &ApiError{400, description[0], description[1]}
}
func (err *ApiError) Error() string {
canonical := err.message
if canonical == "" {
butchered := strings.Split(err.Description, ": ")
if len(butchered) == 2 {
canonical = butchered[1]
// Error implements error interface.
func (err *APIError) Error() string {
msg := err.Message
if msg == "" {
split := strings.Split(err.Description, ": ")
if len(split) == 2 {
msg = split[1]
} else {
canonical = err.Description
msg = err.Description
}
}
return fmt.Sprintf("api error: %s (%d)", canonical, err.Code)
return fmt.Sprintf("api error: %s (%d)", msg, err.Code)
}
var (
//RegExp
apiErrorRx = regexp.MustCompile(`{.+"error_code":(\d+),"description":"(.+)"}`)
//bot creation errors
ErrUnauthorized = &ApiError{401, "Unauthorized", ""}
// NewAPIError returns new APIError instance with given description.
// First element of msgs is Description. The second is optional Message.
func NewAPIError(code int, msgs ...string) *APIError {
err := &APIError{Code: code}
if len(msgs) >= 1 {
err.Description = msgs[0]
}
if len(msgs) >= 2 {
err.Message = msgs[1]
}
return err
}
// not found etc
ErrToForwardNotFound = badRequest("Bad Request: message to forward not found")
ErrToReplyNotFound = badRequest("Bad Request: reply message not found")
ErrMessageTooLong = badRequest("Bad Request: message is too long")
ErrBlockedByUsr = &ApiError{401, "Forbidden: bot was blocked by the user", ""}
ErrToDeleteNotFound = badRequest("Bad Request: message to delete not found")
ErrEmptyMessage = badRequest("Bad Request: message must be non-empty")
//checking
ErrEmptyText = badRequest("Bad Request: text is empty")
ErrEmptyChatID = badRequest("Bad Request: chat_id is empty")
ErrNotFoundChat = badRequest("Bad Request: chat not found")
ErrMessageNotModified = badRequest("Bad Request: message is not modified")
var errorRx = regexp.MustCompile(`{.+"error_code":(\d+),"description":"(.+)"}`)
// Rigts Errors
ErrNoRightsToRestrict = badRequest("Bad Request: not enough rights to restrict/unrestrict chat member")
ErrNoRightsToSendMsg = badRequest("Bad Request: have no rights to send a message")
ErrNoRightsToSendPhoto = badRequest("Bad Request: not enough rights to send photos to the chat")
ErrNoRightsToSendStickers = badRequest("Bad Request: not enough rights to send stickers to the chat")
ErrNoRightsToSendGifs = badRequest("Bad Request: CHAT_SEND_GIFS_FORBIDDEN", "sending GIFS is not allowed in this chat")
ErrNoRightsToDelete = badRequest("Bad Request: message can't be deleted")
ErrKickingChatOwner = badRequest("Bad Request: can't remove chat owner")
var (
// Authorization errors
ErrUnauthorized = NewAPIError(401, "Unauthorized")
ErrBlockedByUsr = NewAPIError(401, "Forbidden: bot was blocked by the user")
// Interacting with group/supergroup after being kicked
ErrInteractKickedG = &ApiError{403, "Forbidden: bot was kicked from the group chat", ""}
ErrInteractKickedSprG = &ApiError{403, "Forbidden: bot was kicked from the supergroup chat", ""}
// Bad request errors
ErrToForwardNotFound = NewAPIError(400, "Bad Request: message to forward not found")
ErrToReplyNotFound = NewAPIError(400, "Bad Request: reply message not found")
ErrMessageTooLong = NewAPIError(400, "Bad Request: message is too long")
ErrToDeleteNotFound = NewAPIError(400, "Bad Request: message to delete not found")
ErrEmptyMessage = NewAPIError(400, "Bad Request: message must be non-empty")
ErrNotFoundChat = NewAPIError(400, "Bad Request: chat not found")
ErrEmptyText = NewAPIError(400, "Bad Request: text is empty")
ErrEmptyChatID = NewAPIError(400, "Bad Request: chat_id is empty")
ErrMessageNotModified = NewAPIError(400, "Bad Request: message is not modified")
ErrWrongTypeOfContent = NewAPIError(400, "Bad Request: wrong type of the web page content")
ErrCantGetHTTPurlContent = NewAPIError(400, "Bad Request: failed to get HTTP URL content")
ErrWrongRemoteFileID = NewAPIError(400, "Bad Request: wrong remote file id specified: can't unserialize it. Wrong last symbol")
ErrFileIdTooShort = NewAPIError(400, "Bad Request: wrong remote file id specified: Wrong string length")
ErrWrongRemoteFileIDsymbol = NewAPIError(400, "Bad Request: wrong remote file id specified: Wrong character in the string")
ErrWrongFileIdentifier = NewAPIError(400, "Bad Request: wrong file identifier/HTTP URL specified")
ErrWrongPadding = NewAPIError(400, "Bad Request: wrong remote file id specified: Wrong padding in the string")
ErrImageProcess = NewAPIError(400, "Bad Request: IMAGE_PROCESS_FAILED", "Image process failed")
ErrTooLarge = NewAPIError(400, "Request Entity Too Large")
ErrWrongStickerpack = NewAPIError(400, "Bad Request: STICKERSET_INVALID", "Stickerset is invalid")
// file errors etc
ErrWrongTypeOfContent = badRequest("Bad Request: wrong type of the web page content")
ErrCantGetHTTPurlContent = badRequest("Bad Request: failed to get HTTP URL content")
ErrWrongRemoteFileID = badRequest("Bad Request: wrong remote file id specified: can't unserialize it. Wrong last symbol")
ErrFileIdTooShort = badRequest("Bad Request: wrong remote file id specified: Wrong string length")
ErrWrongRemoteFileIDsymbol = badRequest("Bad Request: wrong remote file id specified: Wrong character in the string")
ErrWrongFileIdentifier = badRequest("Bad Request: wrong file identifier/HTTP URL specified")
ErrTooLarge = badRequest("Request Entity Too Large")
ErrWrongPadding = badRequest("Bad Request: wrong remote file id specified: Wrong padding in the string") // not my
ErrImageProcess = badRequest("Bad Request: IMAGE_PROCESS_FAILED", "Image process failed")
// No rights errors
ErrNoRightsToRestrict = NewAPIError(400, "Bad Request: not enough rights to restrict/unrestrict chat member")
ErrNoRightsToSendMsg = NewAPIError(400, "Bad Request: have no rights to send a message")
ErrNoRightsToSendPhoto = NewAPIError(400, "Bad Request: not enough rights to send photos to the chat")
ErrNoRightsToSendStickers = NewAPIError(400, "Bad Request: not enough rights to send stickers to the chat")
ErrNoRightsToSendGifs = NewAPIError(400, "Bad Request: CHAT_SEND_GIFS_FORBIDDEN", "sending GIFS is not allowed in this chat")
ErrNoRightsToDelete = NewAPIError(400, "Bad Request: message can't be deleted")
ErrKickingChatOwner = NewAPIError(400, "Bad Request: can't remove chat owner")
// sticker errors
ErrWrongStickerpack = badRequest("Bad Request: STICKERSET_INVALID", "Stickerset is invalid")
// Super/groups errors
ErrInteractKickedG = NewAPIError(403, "Forbidden: bot was kicked from the group chat")
ErrInteractKickedSprG = NewAPIError(403, "Forbidden: bot was kicked from the supergroup chat")
)
// errByDescription returns APIError instance by given description.
func errByDescription(s string) *APIError {
switch s {
case ErrUnauthorized.ʔ():
return ErrUnauthorized
case ErrToForwardNotFound.ʔ():
return ErrToForwardNotFound
case ErrToReplyNotFound.ʔ():
return ErrToReplyNotFound
case ErrMessageTooLong.ʔ():
return ErrMessageTooLong
case ErrBlockedByUsr.ʔ():
return ErrBlockedByUsr
case ErrToDeleteNotFound.ʔ():
return ErrToDeleteNotFound
case ErrEmptyMessage.ʔ():
return ErrEmptyMessage
case ErrEmptyText.ʔ():
return ErrEmptyText
case ErrEmptyChatID.ʔ():
return ErrEmptyChatID
case ErrNotFoundChat.ʔ():
return ErrNotFoundChat
case ErrMessageNotModified.ʔ():
return ErrMessageNotModified
case ErrNoRightsToRestrict.ʔ():
return ErrNoRightsToRestrict
case ErrNoRightsToSendMsg.ʔ():
return ErrNoRightsToSendMsg
case ErrNoRightsToSendPhoto.ʔ():
return ErrNoRightsToSendPhoto
case ErrNoRightsToSendStickers.ʔ():
return ErrNoRightsToSendStickers
case ErrNoRightsToSendGifs.ʔ():
return ErrNoRightsToSendGifs
case ErrNoRightsToDelete.ʔ():
return ErrNoRightsToDelete
case ErrKickingChatOwner.ʔ():
return ErrKickingChatOwner
case ErrInteractKickedG.ʔ():
return ErrKickingChatOwner
case ErrInteractKickedSprG.ʔ():
return ErrInteractKickedSprG
case ErrWrongTypeOfContent.ʔ():
return ErrWrongTypeOfContent
case ErrCantGetHTTPurlContent.ʔ():
return ErrCantGetHTTPurlContent
case ErrWrongRemoteFileID.ʔ():
return ErrWrongRemoteFileID
case ErrFileIdTooShort.ʔ():
return ErrFileIdTooShort
case ErrWrongRemoteFileIDsymbol.ʔ():
return ErrWrongRemoteFileIDsymbol
case ErrWrongFileIdentifier.ʔ():
return ErrWrongFileIdentifier
case ErrTooLarge.ʔ():
return ErrTooLarge
case ErrWrongPadding.ʔ():
return ErrWrongPadding
case ErrImageProcess.ʔ():
return ErrImageProcess
case ErrWrongStickerpack.ʔ():
return ErrWrongStickerpack
default:
return nil
}
}

@ -149,8 +149,8 @@ type Animation struct {
}
// MediaFile returns &Animation.File
func (v *Animation) MediaFile() *File {
return &v.File
func (a *Animation) MediaFile() *File {
return &a.File
}
// Voice object represents a voice note.

@ -43,8 +43,9 @@ func (b *Bot) sendText(to Recipient, text string, opt *SendOptions) (*Message, e
return extractMsgResponse(respJSON)
}
func wrapSystem(err error) error {
return errors.Wrap(err, "system error")
// wrapError returns new wrapped telebot-related error.
func wrapError(err error) error {
return errors.Wrap(err, "telebot")
}
func isUserInList(user *User, list []User) bool {

Loading…
Cancel
Save