| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265 |
- // Copyright (c) 2021 Tulir Asokan
- //
- // This Source Code Form is subject to the terms of the Mozilla Public
- // License, v. 2.0. If a copy of the MPL was not distributed with this
- // file, You can obtain one at http://mozilla.org/MPL/2.0/.
- package whatsmeow
- import (
- "errors"
- "fmt"
- "net/http"
- waBinary "git.bobomao.top/joey/testwh/binary"
- )
- // Miscellaneous errors
- var (
- ErrClientIsNil = errors.New("client is nil")
- ErrNoSession = errors.New("can't encrypt message for device: no signal session established")
- ErrIQTimedOut = errors.New("info query timed out")
- ErrNotConnected = errors.New("websocket not connected")
- ErrNotLoggedIn = errors.New("the store doesn't contain a device JID")
- ErrMessageTimedOut = errors.New("timed out waiting for message send response")
- ErrAlreadyConnected = errors.New("websocket is already connected")
- ErrPhoneNumberTooShort = errors.New("phone number too short")
- ErrPhoneNumberIsNotInternational = errors.New("international phone number required (must not start with 0)")
- ErrQRAlreadyConnected = errors.New("GetQRChannel must be called before connecting")
- ErrQRStoreContainsID = errors.New("GetQRChannel can only be called when there's no user ID in the client's Store")
- ErrNoPushName = errors.New("can't send presence without PushName set")
- ErrNoPrivacyToken = errors.New("no privacy token stored")
- ErrAppStateUpdate = errors.New("server returned error updating app state")
- )
- // Errors that happen while confirming device pairing
- var (
- ErrPairInvalidDeviceIdentityHMAC = errors.New("invalid device identity HMAC in pair success message")
- ErrPairInvalidDeviceSignature = errors.New("invalid device signature in pair success message")
- ErrPairRejectedLocally = errors.New("local PrePairCallback rejected pairing")
- )
- // PairProtoError is included in an events.PairError if the pairing failed due to a protobuf error.
- type PairProtoError struct {
- Message string
- ProtoErr error
- }
- func (err *PairProtoError) Error() string {
- return fmt.Sprintf("%s: %v", err.Message, err.ProtoErr)
- }
- func (err *PairProtoError) Unwrap() error {
- return err.ProtoErr
- }
- // PairDatabaseError is included in an events.PairError if the pairing failed due to being unable to save the credentials to the device store.
- type PairDatabaseError struct {
- Message string
- DBErr error
- }
- func (err *PairDatabaseError) Error() string {
- return fmt.Sprintf("%s: %v", err.Message, err.DBErr)
- }
- func (err *PairDatabaseError) Unwrap() error {
- return err.DBErr
- }
- var (
- // ErrProfilePictureUnauthorized is returned by GetProfilePictureInfo when trying to get the profile picture of a user
- // whose privacy settings prevent you from seeing their profile picture (status code 401).
- ErrProfilePictureUnauthorized = errors.New("the user has hidden their profile picture from you")
- // ErrProfilePictureNotSet is returned by GetProfilePictureInfo when the given user or group doesn't have a profile
- // picture (status code 404).
- ErrProfilePictureNotSet = errors.New("that user or group does not have a profile picture")
- // ErrGroupInviteLinkUnauthorized is returned by GetGroupInviteLink if you don't have the permission to get the link (status code 401).
- ErrGroupInviteLinkUnauthorized = errors.New("you don't have the permission to get the group's invite link")
- // ErrNotInGroup is returned by group info getting methods if you're not in the group (status code 403).
- ErrNotInGroup = errors.New("you're not participating in that group")
- // ErrGroupNotFound is returned by group info getting methods if the group doesn't exist (status code 404).
- ErrGroupNotFound = errors.New("that group does not exist")
- // ErrInviteLinkInvalid is returned by methods that use group invite links if the invite link is malformed.
- ErrInviteLinkInvalid = errors.New("that group invite link is not valid")
- // ErrInviteLinkRevoked is returned by methods that use group invite links if the invite link was valid, but has been revoked and can no longer be used.
- ErrInviteLinkRevoked = errors.New("that group invite link has been revoked")
- // ErrBusinessMessageLinkNotFound is returned by ResolveBusinessMessageLink if the link doesn't exist or has been revoked.
- ErrBusinessMessageLinkNotFound = errors.New("that business message link does not exist or has been revoked")
- // ErrContactQRLinkNotFound is returned by ResolveContactQRLink if the link doesn't exist or has been revoked.
- ErrContactQRLinkNotFound = errors.New("that contact QR link does not exist or has been revoked")
- // ErrInvalidImageFormat is returned by SetGroupPhoto if the given photo is not in the correct format.
- ErrInvalidImageFormat = errors.New("the given data is not a valid image")
- // ErrMediaNotAvailableOnPhone is returned by DecryptMediaRetryNotification if the given event contains error code 2.
- ErrMediaNotAvailableOnPhone = errors.New("media no longer available on phone")
- // ErrUnknownMediaRetryError is returned by DecryptMediaRetryNotification if the given event contains an unknown error code.
- ErrUnknownMediaRetryError = errors.New("unknown media retry error")
- // ErrInvalidDisappearingTimer is returned by SetDisappearingTimer if the given timer is not one of the allowed values.
- ErrInvalidDisappearingTimer = errors.New("invalid disappearing timer provided")
- )
- // Some errors that Client.SendMessage can return
- var (
- ErrBroadcastListUnsupported = errors.New("sending to non-status broadcast lists is not yet supported")
- ErrUnknownServer = errors.New("can't send message to unknown server")
- ErrRecipientADJID = errors.New("message recipient must be a user JID with no device part")
- ErrServerReturnedError = errors.New("server returned error")
- ErrInvalidInlineBotID = errors.New("invalid inline bot ID")
- )
- type DownloadHTTPError struct {
- *http.Response
- }
- func (dhe DownloadHTTPError) Error() string {
- return fmt.Sprintf("download failed with status code %d", dhe.StatusCode)
- }
- func (dhe DownloadHTTPError) Is(other error) bool {
- var otherDHE DownloadHTTPError
- return errors.As(other, &otherDHE) && dhe.StatusCode == otherDHE.StatusCode
- }
- // Some errors that Client.Download can return
- var (
- ErrMediaDownloadFailedWith403 = DownloadHTTPError{Response: &http.Response{StatusCode: 403}}
- ErrMediaDownloadFailedWith404 = DownloadHTTPError{Response: &http.Response{StatusCode: 404}}
- ErrMediaDownloadFailedWith410 = DownloadHTTPError{Response: &http.Response{StatusCode: 410}}
- ErrNoURLPresent = errors.New("no url present")
- ErrFileLengthMismatch = errors.New("file length does not match")
- ErrTooShortFile = errors.New("file too short")
- ErrInvalidMediaHMAC = errors.New("invalid media hmac")
- ErrInvalidMediaEncSHA256 = errors.New("hash of media ciphertext doesn't match")
- ErrInvalidMediaSHA256 = errors.New("hash of media plaintext doesn't match")
- ErrUnknownMediaType = errors.New("unknown media type")
- ErrNothingDownloadableFound = errors.New("didn't find any attachments in message")
- )
- var (
- ErrOriginalMessageSecretNotFound = errors.New("original message secret key not found")
- ErrNotEncryptedReactionMessage = errors.New("given message isn't an encrypted reaction message")
- ErrNotEncryptedCommentMessage = errors.New("given message isn't an encrypted comment message")
- ErrNotSecretEncryptedMessage = errors.New("given message isn't a secret encrypted message")
- ErrNotPollUpdateMessage = errors.New("given message isn't a poll update message")
- )
- type wrappedIQError struct {
- HumanError error
- IQError error
- }
- func (err *wrappedIQError) Error() string {
- return err.HumanError.Error()
- }
- func (err *wrappedIQError) Is(other error) bool {
- return errors.Is(other, err.HumanError)
- }
- func (err *wrappedIQError) Unwrap() error {
- return err.IQError
- }
- func wrapIQError(human, iq error) error {
- return &wrappedIQError{human, iq}
- }
- // IQError is a generic error container for info queries
- type IQError struct {
- Code int
- Text string
- ErrorNode *waBinary.Node
- RawNode *waBinary.Node
- }
- // Common errors returned by info queries for use with errors.Is
- var (
- ErrIQBadRequest error = &IQError{Code: 400, Text: "bad-request"}
- ErrIQNotAuthorized error = &IQError{Code: 401, Text: "not-authorized"}
- ErrIQForbidden error = &IQError{Code: 403, Text: "forbidden"}
- ErrIQNotFound error = &IQError{Code: 404, Text: "item-not-found"}
- ErrIQNotAllowed error = &IQError{Code: 405, Text: "not-allowed"}
- ErrIQNotAcceptable error = &IQError{Code: 406, Text: "not-acceptable"}
- ErrIQGone error = &IQError{Code: 410, Text: "gone"}
- ErrIQResourceLimit error = &IQError{Code: 419, Text: "resource-limit"}
- ErrIQLocked error = &IQError{Code: 423, Text: "locked"}
- ErrIQRateOverLimit error = &IQError{Code: 429, Text: "rate-overlimit"}
- ErrIQInternalServerError error = &IQError{Code: 500, Text: "internal-server-error"}
- ErrIQServiceUnavailable error = &IQError{Code: 503, Text: "service-unavailable"}
- ErrIQPartialServerError error = &IQError{Code: 530, Text: "partial-server-error"}
- )
- func parseIQError(node *waBinary.Node) error {
- var err IQError
- err.RawNode = node
- val, ok := node.GetOptionalChildByTag("error")
- if ok {
- err.ErrorNode = &val
- ag := val.AttrGetter()
- err.Code = ag.OptionalInt("code")
- err.Text = ag.OptionalString("text")
- }
- return &err
- }
- func (iqe *IQError) Error() string {
- if iqe.Code == 0 {
- if iqe.ErrorNode != nil {
- return fmt.Sprintf("info query returned unknown error: %s", iqe.ErrorNode.XMLString())
- } else if iqe.RawNode != nil {
- return fmt.Sprintf("info query returned unexpected response: %s", iqe.RawNode.XMLString())
- } else {
- return "unknown info query error"
- }
- }
- return fmt.Sprintf("info query returned status %d: %s", iqe.Code, iqe.Text)
- }
- func (iqe *IQError) Is(other error) bool {
- otherIQE, ok := other.(*IQError)
- if !ok {
- return false
- } else if iqe.Code != 0 && otherIQE.Code != 0 {
- return otherIQE.Code == iqe.Code && otherIQE.Text == iqe.Text
- } else if iqe.ErrorNode != nil && otherIQE.ErrorNode != nil {
- return iqe.ErrorNode.XMLString() == otherIQE.ErrorNode.XMLString()
- } else {
- return false
- }
- }
- // ElementMissingError is returned by various functions that parse XML elements when a required element is missing.
- type ElementMissingError struct {
- Tag string
- In string
- }
- func (eme *ElementMissingError) Error() string {
- return fmt.Sprintf("missing <%s> element in %s", eme.Tag, eme.In)
- }
- var ErrIQDisconnected = &DisconnectedError{Action: "info query"}
- // DisconnectedError is returned if the websocket disconnects before an info query or other request gets a response.
- type DisconnectedError struct {
- Action string
- Node *waBinary.Node
- }
- func (err *DisconnectedError) Error() string {
- return fmt.Sprintf("websocket disconnected before %s returned response", err.Action)
- }
- func (err *DisconnectedError) Is(other error) bool {
- otherDisc, ok := other.(*DisconnectedError)
- if !ok {
- return false
- }
- return otherDisc.Action == err.Action
- }
|