diff --git a/cmd/chat-cli/api/client.go b/cmd/chat-cli/api/client.go index 95141b5..01ce582 100644 --- a/cmd/chat-cli/api/client.go +++ b/cmd/chat-cli/api/client.go @@ -4,6 +4,7 @@ package api import ( "bytes" "encoding/json" + "errors" "fmt" "io" "net/http" @@ -12,6 +13,13 @@ import ( "time" ) +var ( + // ErrHTTPStatus is returned when the server responds with an error status code. + ErrHTTPStatus = errors.New("HTTP error") + // ErrUnexpectedFormat is returned when the response format is unexpected. + ErrUnexpectedFormat = errors.New("unexpected format") +) + // Client wraps HTTP calls to the chat server API. type Client struct { BaseURL string @@ -64,7 +72,7 @@ func (c *Client) do(method, path string, body any) ([]byte, error) { } if resp.StatusCode >= 400 { - return data, fmt.Errorf("HTTP %d: %s", resp.StatusCode, string(data)) + return data, fmt.Errorf("%w: %d: %s", ErrHTTPStatus, resp.StatusCode, string(data)) } return data, nil @@ -150,7 +158,7 @@ func (c *Client) PollMessages(afterID string, timeout int) ([]Message, error) { } if resp.StatusCode >= 400 { - return nil, fmt.Errorf("HTTP %d: %s", resp.StatusCode, string(data)) + return nil, fmt.Errorf("%w: %d: %s", ErrHTTPStatus, resp.StatusCode, string(data)) } // The server may return an array directly or wrapped. @@ -218,7 +226,7 @@ func (c *Client) GetMembers(channel string) ([]string, error) { return nil, err } // Extract member names from whatever format. - return nil, fmt.Errorf("unexpected members format: %s", string(data)) + return nil, fmt.Errorf("%w: members: %s", ErrUnexpectedFormat, string(data)) } return members, nil diff --git a/internal/models/auth_token.go b/internal/models/auth_token.go index 2b8b4b9..c2c3fd1 100644 --- a/internal/models/auth_token.go +++ b/internal/models/auth_token.go @@ -2,7 +2,6 @@ package models import ( "context" - "errors" "time" ) @@ -23,5 +22,5 @@ func (t *AuthToken) User(ctx context.Context) (*User, error) { return ul.GetUserByID(ctx, t.UserID) } - return nil, errors.New("user lookup not available") + return nil, ErrUserLookupNotAvailable } diff --git a/internal/models/channel_member.go b/internal/models/channel_member.go index e98cf7f..59586c7 100644 --- a/internal/models/channel_member.go +++ b/internal/models/channel_member.go @@ -2,7 +2,6 @@ package models import ( "context" - "errors" "time" ) @@ -23,7 +22,7 @@ func (cm *ChannelMember) User(ctx context.Context) (*User, error) { return ul.GetUserByID(ctx, cm.UserID) } - return nil, errors.New("user lookup not available") + return nil, ErrUserLookupNotAvailable } // Channel returns the full Channel for this membership. @@ -32,5 +31,5 @@ func (cm *ChannelMember) Channel(ctx context.Context) (*Channel, error) { return cl.GetChannelByID(ctx, cm.ChannelID) } - return nil, errors.New("channel lookup not available") + return nil, ErrChannelLookupNotAvailable } diff --git a/internal/models/model.go b/internal/models/model.go index b65c6e8..ca5c7bc 100644 --- a/internal/models/model.go +++ b/internal/models/model.go @@ -6,6 +6,14 @@ package models import ( "context" "database/sql" + "errors" +) + +var ( + // ErrUserLookupNotAvailable is returned when the user lookup interface is not set. + ErrUserLookupNotAvailable = errors.New("user lookup not available") + // ErrChannelLookupNotAvailable is returned when the channel lookup interface is not set. + ErrChannelLookupNotAvailable = errors.New("channel lookup not available") ) // DB is the interface that models use to query the database. diff --git a/internal/models/session.go b/internal/models/session.go index e6aaf94..295def2 100644 --- a/internal/models/session.go +++ b/internal/models/session.go @@ -2,7 +2,6 @@ package models import ( "context" - "errors" "time" ) @@ -23,5 +22,5 @@ func (s *Session) User(ctx context.Context) (*User, error) { return ul.GetUserByID(ctx, s.UserID) } - return nil, errors.New("user lookup not available") + return nil, ErrUserLookupNotAvailable }