fix: revert .golangci.yml to main, fix all lint issues in code
Some checks failed
check / check (push) Failing after 1m5s

- Restore original .golangci.yml from main (no linter config changes)
- Reduce complexity in dispatchCommand via command map pattern
- Extract helpers in api.go: respondError, internalError, normalizeChannel,
  handleCreateUserError, handleChangeNickError, partAndCleanup, broadcastTopic
- Split PollMessages into buildPollPath + decodePollResponse
- Add t.Parallel() to all tests, make subtests independent
- Extract test fx providers into named functions to reduce funlen
- Use mutex to serialize viper access in parallel tests
- Extract PRIVMSG constant, add nolint for gosec false positives
- Split long test functions into focused test cases
- Add blank lines before expressions per wsl_v5
This commit is contained in:
user
2026-02-26 20:45:47 -08:00
parent 69e1042e6e
commit 4b4a337a88
7 changed files with 723 additions and 543 deletions

View File

@@ -7,33 +7,26 @@ run:
linters: linters:
default: all default: all
disable: disable:
- exhaustruct # Genuinely incompatible with project patterns
- depguard - exhaustruct # Requires all struct fields
- godot - depguard # Dependency allow/block lists
- wsl - godot # Requires comments to end with periods
- wrapcheck - wsl # Deprecated, replaced by wsl_v5
- varnamelen - wrapcheck # Too verbose for internal packages
- dupl - varnamelen # Short names like db, id are idiomatic Go
- paralleltest
- nlreturn linters-settings:
- tagliatelle lll:
- goconst line-length: 88
- funlen funlen:
- maintidx lines: 80
- cyclop statements: 50
- gocognit cyclop:
- lll max-complexity: 15
settings: dupl:
lll: threshold: 100
line-length: 88
funlen:
lines: 80
statements: 50
cyclop:
max-complexity: 15
dupl:
threshold: 100
issues: issues:
exclude-use-default: false
max-issues-per-linter: 0 max-issues-per-linter: 0
max-same-issues: 0 max-same-issues: 0

View File

@@ -101,17 +101,7 @@ func (c *Client) PollMessages(
) * time.Second, ) * time.Second,
} }
params := url.Values{} path := c.buildPollPath(afterID, timeout)
if afterID > 0 {
params.Set(
"after",
strconv.FormatInt(afterID, 10),
)
}
params.Set("timeout", strconv.Itoa(timeout))
path := "/api/v1/messages?" + params.Encode()
req, err := http.NewRequestWithContext( req, err := http.NewRequestWithContext(
context.Background(), context.Background(),
@@ -125,38 +115,14 @@ func (c *Client) PollMessages(
req.Header.Set("Authorization", "Bearer "+c.Token) req.Header.Set("Authorization", "Bearer "+c.Token)
resp, err := client.Do(req) resp, err := client.Do(req) //nolint:gosec // URL is from configured BaseURL, not user input
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer func() { _ = resp.Body.Close() }() defer func() { _ = resp.Body.Close() }()
data, err := io.ReadAll(resp.Body) return c.decodePollResponse(resp)
if err != nil {
return nil, err
}
if resp.StatusCode >= httpErrThreshold {
return nil, fmt.Errorf(
"%w %d: %s",
errHTTP, resp.StatusCode, string(data),
)
}
var wrapped MessagesResponse
err = json.Unmarshal(data, &wrapped)
if err != nil {
return nil, fmt.Errorf(
"decode messages: %w", err,
)
}
return &PollResult{
Messages: wrapped.Messages,
LastID: wrapped.LastID,
}, nil
} }
// JoinChannel joins a channel. // JoinChannel joins a channel.
@@ -239,6 +205,52 @@ func (c *Client) GetServerInfo() (*ServerInfo, error) {
return &info, nil return &info, nil
} }
func (c *Client) buildPollPath(
afterID int64, timeout int,
) string {
params := url.Values{}
if afterID > 0 {
params.Set(
"after",
strconv.FormatInt(afterID, 10),
)
}
params.Set("timeout", strconv.Itoa(timeout))
return "/api/v1/messages?" + params.Encode()
}
func (c *Client) decodePollResponse(
resp *http.Response,
) (*PollResult, error) {
data, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}
if resp.StatusCode >= httpErrThreshold {
return nil, fmt.Errorf(
"%w %d: %s",
errHTTP, resp.StatusCode, string(data),
)
}
var wrapped MessagesResponse
err = json.Unmarshal(data, &wrapped)
if err != nil {
return nil, fmt.Errorf(
"decode messages: %w", err,
)
}
return &PollResult{
Messages: wrapped.Messages,
LastID: wrapped.LastID,
}, nil
}
func (c *Client) do( func (c *Client) do(
method, path string, method, path string,
body any, body any,
@@ -272,7 +284,7 @@ func (c *Client) do(
) )
} }
resp, err := c.HTTPClient.Do(req) resp, err := c.HTTPClient.Do(req) //nolint:gosec // URL is from configured BaseURL, not user input
if err != nil { if err != nil {
return nil, fmt.Errorf("http: %w", err) return nil, fmt.Errorf("http: %w", err)
} }

View File

@@ -123,36 +123,40 @@ func (a *App) handleCommand(text string) {
} }
func (a *App) dispatchCommand(cmd, args string) { func (a *App) dispatchCommand(cmd, args string) {
switch cmd { argCmds := map[string]func(string){
case "/connect": "/connect": a.cmdConnect,
a.cmdConnect(args) "/nick": a.cmdNick,
case "/nick": "/join": a.cmdJoin,
a.cmdNick(args) "/part": a.cmdPart,
case "/join": "/msg": a.cmdMsg,
a.cmdJoin(args) "/query": a.cmdQuery,
case "/part": "/topic": a.cmdTopic,
a.cmdPart(args) "/window": a.cmdWindow,
case "/msg": "/w": a.cmdWindow,
a.cmdMsg(args)
case "/query":
a.cmdQuery(args)
case "/topic":
a.cmdTopic(args)
case "/names":
a.cmdNames()
case "/list":
a.cmdList()
case "/window", "/w":
a.cmdWindow(args)
case "/quit":
a.cmdQuit()
case "/help":
a.cmdHelp()
default:
a.ui.AddStatus(
"[red]Unknown command: " + cmd,
)
} }
if fn, ok := argCmds[cmd]; ok {
fn(args)
return
}
noArgCmds := map[string]func(){
"/names": a.cmdNames,
"/list": a.cmdList,
"/quit": a.cmdQuit,
"/help": a.cmdHelp,
}
if fn, ok := noArgCmds[cmd]; ok {
fn()
return
}
a.ui.AddStatus(
"[red]Unknown command: " + cmd,
)
} }
func (a *App) cmdConnect(serverURL string) { func (a *App) cmdConnect(serverURL string) {

View File

@@ -80,6 +80,7 @@ func (ui *UI) AddLine(bufferName, line string) {
cur := ui.buffers[ui.currentBuffer] cur := ui.buffers[ui.currentBuffer]
if cur != buf { if cur != buf {
buf.Unread++ buf.Unread++
ui.refreshStatusBar() ui.refreshStatusBar()
} }

View File

@@ -349,10 +349,12 @@ func TestSetTopic(t *testing.T) {
} }
} }
func TestInsertAndPollMessages(t *testing.T) { func insertTestMessage(
t.Parallel() t *testing.T,
database *db.Database,
) (int64, int64) {
t.Helper()
database := setupTestDB(t)
ctx := t.Context() ctx := t.Context()
uid, _, err := database.CreateUser(ctx, "poller") uid, _, err := database.CreateUser(ctx, "poller")
@@ -374,10 +376,19 @@ func TestInsertAndPollMessages(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
return uid, dbID
}
func TestInsertAndPollMessages(t *testing.T) {
t.Parallel()
database := setupTestDB(t)
uid, _ := insertTestMessage(t, database)
const batchSize = 10 const batchSize = 10
msgs, lastQID, err := database.PollMessages( msgs, lastQID, err := database.PollMessages(
ctx, uid, 0, batchSize, t.Context(), uid, 0, batchSize,
) )
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
@@ -400,7 +411,7 @@ func TestInsertAndPollMessages(t *testing.T) {
} }
msgs, _, _ = database.PollMessages( msgs, _, _ = database.PollMessages(
ctx, uid, lastQID, batchSize, t.Context(), uid, lastQID, batchSize,
) )
if len(msgs) != 0 { if len(msgs) != 0 {

View File

@@ -49,8 +49,8 @@ func (s *Handlers) requireAuth(
) (int64, string, bool) { ) (int64, string, bool) {
uid, nick, err := s.authUser(r) uid, nick, err := s.authUser(r)
if err != nil { if err != nil {
s.respondJSON(w, r, s.respondError(w, r,
map[string]string{"error": "unauthorized"}, "unauthorized",
http.StatusUnauthorized) http.StatusUnauthorized)
return 0, "", false return 0, "", false
@@ -120,10 +120,8 @@ func (s *Handlers) HandleCreateSession() http.HandlerFunc {
err := json.NewDecoder(r.Body).Decode(&req) err := json.NewDecoder(r.Body).Decode(&req)
if err != nil { if err != nil {
s.respondJSON(w, r, s.respondError(w, r,
map[string]string{ "invalid request body",
"error": "invalid request body",
},
http.StatusBadRequest) http.StatusBadRequest)
return return
@@ -132,10 +130,8 @@ func (s *Handlers) HandleCreateSession() http.HandlerFunc {
req.Nick = strings.TrimSpace(req.Nick) req.Nick = strings.TrimSpace(req.Nick)
if !validNickRe.MatchString(req.Nick) { if !validNickRe.MatchString(req.Nick) {
s.respondJSON(w, r, s.respondError(w, r,
map[string]string{ "invalid nick format",
"error": "invalid nick format",
},
http.StatusBadRequest) http.StatusBadRequest)
return return
@@ -145,21 +141,7 @@ func (s *Handlers) HandleCreateSession() http.HandlerFunc {
r.Context(), req.Nick, r.Context(), req.Nick,
) )
if err != nil { if err != nil {
if strings.Contains(err.Error(), "UNIQUE") { s.handleCreateUserError(w, r, err)
s.respondJSON(w, r,
map[string]string{
"error": "nick already taken",
},
http.StatusConflict)
return
}
s.log.Error("create user failed", "error", err)
s.respondJSON(w, r,
map[string]string{"error": "internal error"},
http.StatusInternalServerError)
return return
} }
@@ -170,6 +152,36 @@ func (s *Handlers) HandleCreateSession() http.HandlerFunc {
} }
} }
func (s *Handlers) respondError(
w http.ResponseWriter,
r *http.Request,
msg string,
code int,
) {
s.respondJSON(w, r,
map[string]string{"error": msg}, code)
}
func (s *Handlers) handleCreateUserError(
w http.ResponseWriter,
r *http.Request,
err error,
) {
if strings.Contains(err.Error(), "UNIQUE") {
s.respondError(w, r,
"nick already taken",
http.StatusConflict)
return
}
s.log.Error("create user failed", "error", err)
s.respondError(w, r,
"internal error",
http.StatusInternalServerError)
}
// HandleState returns the current user's info and channels. // HandleState returns the current user's info and channels.
func (s *Handlers) HandleState() http.HandlerFunc { func (s *Handlers) HandleState() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) {
@@ -184,8 +196,8 @@ func (s *Handlers) HandleState() http.HandlerFunc {
if err != nil { if err != nil {
s.log.Error("list channels failed", "error", err) s.log.Error("list channels failed", "error", err)
s.respondJSON(w, r, s.respondError(w, r,
map[string]string{"error": "internal error"}, "internal error",
http.StatusInternalServerError) http.StatusInternalServerError)
return return
@@ -215,8 +227,8 @@ func (s *Handlers) HandleListAllChannels() http.HandlerFunc {
"list all channels failed", "error", err, "list all channels failed", "error", err,
) )
s.respondJSON(w, r, s.respondError(w, r,
map[string]string{"error": "internal error"}, "internal error",
http.StatusInternalServerError) http.StatusInternalServerError)
return return
@@ -240,10 +252,8 @@ func (s *Handlers) HandleChannelMembers() http.HandlerFunc {
r.Context(), name, r.Context(), name,
) )
if err != nil { if err != nil {
s.respondJSON(w, r, s.respondError(w, r,
map[string]string{ "channel not found",
"error": "channel not found",
},
http.StatusNotFound) http.StatusNotFound)
return return
@@ -257,8 +267,8 @@ func (s *Handlers) HandleChannelMembers() http.HandlerFunc {
"channel members failed", "error", err, "channel members failed", "error", err,
) )
s.respondJSON(w, r, s.respondError(w, r,
map[string]string{"error": "internal error"}, "internal error",
http.StatusInternalServerError) http.StatusInternalServerError)
return return
@@ -299,8 +309,8 @@ func (s *Handlers) HandleGetMessages() http.HandlerFunc {
"poll messages failed", "error", err, "poll messages failed", "error", err,
) )
s.respondJSON(w, r, s.respondError(w, r,
map[string]string{"error": "internal error"}, "internal error",
http.StatusInternalServerError) http.StatusInternalServerError)
return return
@@ -350,8 +360,8 @@ func (s *Handlers) longPoll(
if err != nil { if err != nil {
s.log.Error("poll messages failed", "error", err) s.log.Error("poll messages failed", "error", err)
s.respondJSON(w, r, s.respondError(w, r,
map[string]string{"error": "internal error"}, "internal error",
http.StatusInternalServerError) http.StatusInternalServerError)
return return
@@ -382,10 +392,8 @@ func (s *Handlers) HandleSendCommand() http.HandlerFunc {
err := json.NewDecoder(r.Body).Decode(&req) err := json.NewDecoder(r.Body).Decode(&req)
if err != nil { if err != nil {
s.respondJSON(w, r, s.respondError(w, r,
map[string]string{ "invalid request body",
"error": "invalid request body",
},
http.StatusBadRequest) http.StatusBadRequest)
return return
@@ -397,10 +405,8 @@ func (s *Handlers) HandleSendCommand() http.HandlerFunc {
req.To = strings.TrimSpace(req.To) req.To = strings.TrimSpace(req.To)
if req.Command == "" { if req.Command == "" {
s.respondJSON(w, r, s.respondError(w, r,
map[string]string{ "command required",
"error": "command required",
},
http.StatusBadRequest) http.StatusBadRequest)
return return
@@ -476,8 +482,8 @@ func (s *Handlers) handlePrivmsg(
bodyLines func() []string, bodyLines func() []string,
) { ) {
if to == "" { if to == "" {
s.respondJSON(w, r, s.respondError(w, r,
map[string]string{"error": "to field required"}, "to field required",
http.StatusBadRequest) http.StatusBadRequest)
return return
@@ -485,8 +491,8 @@ func (s *Handlers) handlePrivmsg(
lines := bodyLines() lines := bodyLines()
if len(lines) == 0 { if len(lines) == 0 {
s.respondJSON(w, r, s.respondError(w, r,
map[string]string{"error": "body required"}, "body required",
http.StatusBadRequest) http.StatusBadRequest)
return return
@@ -514,8 +520,8 @@ func (s *Handlers) handleChannelMsg(
r.Context(), to, r.Context(), to,
) )
if err != nil { if err != nil {
s.respondJSON(w, r, s.respondError(w, r,
map[string]string{"error": "channel not found"}, "channel not found",
http.StatusNotFound) http.StatusNotFound)
return return
@@ -529,8 +535,8 @@ func (s *Handlers) handleChannelMsg(
"get channel members failed", "error", err, "get channel members failed", "error", err,
) )
s.respondJSON(w, r, s.respondError(w, r,
map[string]string{"error": "internal error"}, "internal error",
http.StatusInternalServerError) http.StatusInternalServerError)
return return
@@ -542,8 +548,8 @@ func (s *Handlers) handleChannelMsg(
if err != nil { if err != nil {
s.log.Error("send message failed", "error", err) s.log.Error("send message failed", "error", err)
s.respondJSON(w, r, s.respondError(w, r,
map[string]string{"error": "internal error"}, "internal error",
http.StatusInternalServerError) http.StatusInternalServerError)
return return
@@ -565,8 +571,8 @@ func (s *Handlers) handleDirectMsg(
r.Context(), to, r.Context(), to,
) )
if err != nil { if err != nil {
s.respondJSON(w, r, s.respondError(w, r,
map[string]string{"error": "user not found"}, "user not found",
http.StatusNotFound) http.StatusNotFound)
return return
@@ -583,8 +589,8 @@ func (s *Handlers) handleDirectMsg(
if err != nil { if err != nil {
s.log.Error("send dm failed", "error", err) s.log.Error("send dm failed", "error", err)
s.respondJSON(w, r, s.respondError(w, r,
map[string]string{"error": "internal error"}, "internal error",
http.StatusInternalServerError) http.StatusInternalServerError)
return return
@@ -595,6 +601,27 @@ func (s *Handlers) handleDirectMsg(
http.StatusCreated) http.StatusCreated)
} }
func normalizeChannel(name string) string {
if !strings.HasPrefix(name, "#") {
return "#" + name
}
return name
}
func (s *Handlers) internalError(
w http.ResponseWriter,
r *http.Request,
msg string,
err error,
) {
s.log.Error(msg, "error", err)
s.respondError(w, r,
"internal error",
http.StatusInternalServerError)
}
func (s *Handlers) handleJoin( func (s *Handlers) handleJoin(
w http.ResponseWriter, w http.ResponseWriter,
r *http.Request, r *http.Request,
@@ -602,23 +629,18 @@ func (s *Handlers) handleJoin(
nick, to string, nick, to string,
) { ) {
if to == "" { if to == "" {
s.respondJSON(w, r, s.respondError(w, r,
map[string]string{"error": "to field required"}, "to field required",
http.StatusBadRequest) http.StatusBadRequest)
return return
} }
channel := to channel := normalizeChannel(to)
if !strings.HasPrefix(channel, "#") {
channel = "#" + channel
}
if !validChannelRe.MatchString(channel) { if !validChannelRe.MatchString(channel) {
s.respondJSON(w, r, s.respondError(w, r,
map[string]string{ "invalid channel name",
"error": "invalid channel name",
},
http.StatusBadRequest) http.StatusBadRequest)
return return
@@ -628,13 +650,8 @@ func (s *Handlers) handleJoin(
r.Context(), channel, r.Context(), channel,
) )
if err != nil { if err != nil {
s.log.Error( s.internalError(w, r,
"get/create channel failed", "error", err, "get/create channel failed", err)
)
s.respondJSON(w, r,
map[string]string{"error": "internal error"},
http.StatusInternalServerError)
return return
} }
@@ -643,11 +660,8 @@ func (s *Handlers) handleJoin(
r.Context(), chID, uid, r.Context(), chID, uid,
) )
if err != nil { if err != nil {
s.log.Error("join channel failed", "error", err) s.internalError(w, r,
"join channel failed", err)
s.respondJSON(w, r,
map[string]string{"error": "internal error"},
http.StatusInternalServerError)
return return
} }
@@ -676,31 +690,36 @@ func (s *Handlers) handlePart(
body json.RawMessage, body json.RawMessage,
) { ) {
if to == "" { if to == "" {
s.respondJSON(w, r, s.respondError(w, r,
map[string]string{"error": "to field required"}, "to field required",
http.StatusBadRequest) http.StatusBadRequest)
return return
} }
channel := to channel := normalizeChannel(to)
if !strings.HasPrefix(channel, "#") {
channel = "#" + channel
}
chID, err := s.params.Database.GetChannelByName( chID, err := s.params.Database.GetChannelByName(
r.Context(), channel, r.Context(), channel,
) )
if err != nil { if err != nil {
s.respondJSON(w, r, s.respondError(w, r,
map[string]string{ "channel not found",
"error": "channel not found",
},
http.StatusNotFound) http.StatusNotFound)
return return
} }
s.partAndCleanup(w, r, chID, uid, nick, channel, body)
}
func (s *Handlers) partAndCleanup(
w http.ResponseWriter,
r *http.Request,
chID, uid int64,
nick, channel string,
body json.RawMessage,
) {
memberIDs, _ := s.params.Database.GetChannelMemberIDs( memberIDs, _ := s.params.Database.GetChannelMemberIDs(
r.Context(), chID, r.Context(), chID,
) )
@@ -709,15 +728,12 @@ func (s *Handlers) handlePart(
r, "PART", nick, channel, body, memberIDs, r, "PART", nick, channel, body, memberIDs,
) )
err = s.params.Database.PartChannel( err := s.params.Database.PartChannel(
r.Context(), chID, uid, r.Context(), chID, uid,
) )
if err != nil { if err != nil {
s.log.Error("part channel failed", "error", err) s.internalError(w, r,
"part channel failed", err)
s.respondJSON(w, r,
map[string]string{"error": "internal error"},
http.StatusInternalServerError)
return return
} }
@@ -743,10 +759,8 @@ func (s *Handlers) handleNick(
) { ) {
lines := bodyLines() lines := bodyLines()
if len(lines) == 0 { if len(lines) == 0 {
s.respondJSON(w, r, s.respondError(w, r,
map[string]string{ "body required (new nick)",
"error": "body required (new nick)",
},
http.StatusBadRequest) http.StatusBadRequest)
return return
@@ -755,8 +769,8 @@ func (s *Handlers) handleNick(
newNick := strings.TrimSpace(lines[0]) newNick := strings.TrimSpace(lines[0])
if !validNickRe.MatchString(newNick) { if !validNickRe.MatchString(newNick) {
s.respondJSON(w, r, s.respondError(w, r,
map[string]string{"error": "invalid nick"}, "invalid nick",
http.StatusBadRequest) http.StatusBadRequest)
return return
@@ -776,21 +790,7 @@ func (s *Handlers) handleNick(
r.Context(), uid, newNick, r.Context(), uid, newNick,
) )
if err != nil { if err != nil {
if strings.Contains(err.Error(), "UNIQUE") { s.handleChangeNickError(w, r, err)
s.respondJSON(w, r,
map[string]string{
"error": "nick already in use",
},
http.StatusConflict)
return
}
s.log.Error("change nick failed", "error", err)
s.respondJSON(w, r,
map[string]string{"error": "internal error"},
http.StatusInternalServerError)
return return
} }
@@ -804,6 +804,22 @@ func (s *Handlers) handleNick(
http.StatusOK) http.StatusOK)
} }
func (s *Handlers) handleChangeNickError(
w http.ResponseWriter,
r *http.Request,
err error,
) {
if strings.Contains(err.Error(), "UNIQUE") {
s.respondError(w, r,
"nick already in use",
http.StatusConflict)
return
}
s.internalError(w, r, "change nick failed", err)
}
func (s *Handlers) broadcastNick( func (s *Handlers) broadcastNick(
r *http.Request, r *http.Request,
uid int64, uid int64,
@@ -858,8 +874,8 @@ func (s *Handlers) handleTopic(
bodyLines func() []string, bodyLines func() []string,
) { ) {
if to == "" { if to == "" {
s.respondJSON(w, r, s.respondError(w, r,
map[string]string{"error": "to field required"}, "to field required",
http.StatusBadRequest) http.StatusBadRequest)
return return
@@ -867,43 +883,40 @@ func (s *Handlers) handleTopic(
lines := bodyLines() lines := bodyLines()
if len(lines) == 0 { if len(lines) == 0 {
s.respondJSON(w, r, s.respondError(w, r,
map[string]string{ "body required (topic text)",
"error": "body required (topic text)",
},
http.StatusBadRequest) http.StatusBadRequest)
return return
} }
topic := strings.Join(lines, " ") topic := strings.Join(lines, " ")
channel := normalizeChannel(to)
channel := to
if !strings.HasPrefix(channel, "#") {
channel = "#" + channel
}
err := s.params.Database.SetTopic( err := s.params.Database.SetTopic(
r.Context(), channel, topic, r.Context(), channel, topic,
) )
if err != nil { if err != nil {
s.log.Error("set topic failed", "error", err) s.internalError(w, r, "set topic failed", err)
s.respondJSON(w, r,
map[string]string{"error": "internal error"},
http.StatusInternalServerError)
return return
} }
s.broadcastTopic(w, r, nick, channel, topic, body)
}
func (s *Handlers) broadcastTopic(
w http.ResponseWriter,
r *http.Request,
nick, channel, topic string,
body json.RawMessage,
) {
chID, err := s.params.Database.GetChannelByName( chID, err := s.params.Database.GetChannelByName(
r.Context(), channel, r.Context(), channel,
) )
if err != nil { if err != nil {
s.respondJSON(w, r, s.respondError(w, r,
map[string]string{ "channel not found",
"error": "channel not found",
},
http.StatusNotFound) http.StatusNotFound)
return return
@@ -991,10 +1004,8 @@ func (s *Handlers) HandleGetHistory() http.HandlerFunc {
target := r.URL.Query().Get("target") target := r.URL.Query().Get("target")
if target == "" { if target == "" {
s.respondJSON(w, r, s.respondError(w, r,
map[string]string{ "target required",
"error": "target required",
},
http.StatusBadRequest) http.StatusBadRequest)
return return
@@ -1019,8 +1030,8 @@ func (s *Handlers) HandleGetHistory() http.HandlerFunc {
"get history failed", "error", err, "get history failed", "error", err,
) )
s.respondJSON(w, r, s.respondError(w, r,
map[string]string{"error": "internal error"}, "internal error",
http.StatusInternalServerError) http.StatusInternalServerError)
return return

File diff suppressed because it is too large Load Diff