fix: unsilence all error returns from SQL Exec, Bot API calls, and migrations

This commit is contained in:
2026-06-24 20:03:24 +03:30
parent 4165839477
commit e7e4dc7bfe
8 changed files with 227 additions and 193 deletions

View File

@@ -87,18 +87,18 @@ func (h *Handler) handleActionMsg(ctx context.Context, msg *models.Message, fn a
return
}
kb := mainKeyboard()
h.Bot.SendMessage(ctx, &bot.SendMessageParams{ChatID: msg.Chat.ID, Text: text, ReplyMarkup: kb})
h.sendWithKB(ctx, msg.Chat.ID, text, kb)
}
// handleActionCallback runs an action function and edits the callback message with the result.
func (h *Handler) handleActionCallback(ctx context.Context, chatID int64, msgID int, callbackID string, fn actionFunc) {
defer h.Bot.AnswerCallbackQuery(ctx, &bot.AnswerCallbackQueryParams{CallbackQueryID: callbackID})
defer h.answerCb(ctx, callbackID)
text, err := fn(chatID)
if err != nil {
text = err.Error()
}
kb := backKeyboard()
h.Bot.EditMessageText(ctx, &bot.EditMessageTextParams{ChatID: chatID, MessageID: msgID, Text: text, ReplyMarkup: kb})
h.editText(ctx, chatID, msgID, text, &kb)
}
// HandleMessage routes incoming text messages to the appropriate handler.
@@ -126,7 +126,9 @@ func (h *Handler) HandleMessage(ctx context.Context, msg *models.Message) {
loc := loadLocation(user.Timezone)
event, err := h.getEventByID(user.ID, pn.eventID)
if err == nil {
h.DB.SetEventNote(pn.eventID, msg.Text)
if err := h.DB.SetEventNote(pn.eventID, msg.Text); err != nil {
slog.Error("failed to save event note", "event_id", pn.eventID, "error", err)
}
date := time.Unix(event.OccurredAt, 0).In(loc).Format("2006-01-02")
h.sendDayView(ctx, msg.Chat.ID, 0, user, date, loc, true)
}
@@ -172,16 +174,16 @@ func (h *Handler) HandleMessage(ctx context.Context, msg *models.Message) {
// HandleCallback routes inline callback queries to the appropriate handler.
func (h *Handler) HandleCallback(ctx context.Context, cb *models.CallbackQuery) {
if len(h.AllowedUsers) > 0 && !h.AllowedUsers[cb.Message.Message.Chat.ID] {
h.Bot.AnswerCallbackQuery(ctx, &bot.AnswerCallbackQueryParams{CallbackQueryID: cb.ID, Text: "Unauthorized"})
h.answerCbWithText(ctx, cb.ID, "Unauthorized")
return
}
user, err := h.getOrCreateUser(cb.Message.Message.Chat.ID)
if err != nil {
h.Bot.AnswerCallbackQuery(ctx, &bot.AnswerCallbackQueryParams{CallbackQueryID: cb.ID})
h.answerCb(ctx, cb.ID)
return
}
if h.isRateLimited(user.ID) {
h.Bot.AnswerCallbackQuery(ctx, &bot.AnswerCallbackQueryParams{CallbackQueryID: cb.ID})
h.answerCb(ctx, cb.ID)
return
}
slog.Info("callback", "chat_id", cb.Message.Message.Chat.ID, "data", cb.Data)
@@ -200,7 +202,7 @@ func (h *Handler) HandleCallback(ctx context.Context, cb *models.CallbackQuery)
case "export":
h.exportCallback(ctx, chatID, msgID, cb.ID)
case "noop":
h.Bot.AnswerCallbackQuery(ctx, &bot.AnswerCallbackQueryParams{CallbackQueryID: cb.ID})
h.answerCb(ctx, cb.ID)
case "dayoff":
h.handleActionCallback(ctx, chatID, msgID, cb.ID, h.dayOff)
case "settings":
@@ -276,7 +278,7 @@ func (h *Handler) handleStart(ctx context.Context, msg *models.Message) {
}
slog.Info("start", "user_id", user.ID, "chat_id", msg.Chat.ID)
kb := mainKeyboard()
h.Bot.SendMessage(ctx, &bot.SendMessageParams{ChatID: msg.Chat.ID, Text: h.buildStatusText(msg.Chat.ID), ReplyMarkup: kb})
h.sendWithKB(ctx, msg.Chat.ID, h.buildStatusText(msg.Chat.ID), kb)
}
// handleHelp shows the list of available commands.
@@ -367,20 +369,20 @@ func (h *Handler) handleWorkTypeMsg(ctx context.Context, msg *models.Message) {
return
}
text, kb := h.buildWorkTypeKeyboard(user, day)
h.Bot.SendMessage(ctx, &bot.SendMessageParams{ChatID: msg.Chat.ID, Text: text, ReplyMarkup: kb})
h.sendWithKB(ctx, msg.Chat.ID, text, kb)
}
// workTypeCallback shows the work type picker (inline edit).
func (h *Handler) workTypeCallback(ctx context.Context, chatID int64, msgID int, callbackID string) {
defer h.Bot.AnswerCallbackQuery(ctx, &bot.AnswerCallbackQueryParams{CallbackQueryID: callbackID})
defer h.answerCb(ctx, callbackID)
user, day, err := h.getUserToday(chatID)
if err != nil {
kb := backKeyboard()
h.Bot.EditMessageText(ctx, &bot.EditMessageTextParams{ChatID: chatID, MessageID: msgID, Text: "Error loading work types", ReplyMarkup: kb})
h.editText(ctx, chatID, msgID, "Error loading work types", &kb)
return
}
text, kb := h.buildWorkTypeKeyboard(user, day)
h.Bot.EditMessageText(ctx, &bot.EditMessageTextParams{ChatID: chatID, MessageID: msgID, Text: text, ReplyMarkup: kb})
h.editText(ctx, chatID, msgID, text, &kb)
}
// buildWorkTypeKeyboard returns the work type selection keyboard.
@@ -407,7 +409,7 @@ func (h *Handler) buildWorkTypeKeyboard(user *db.User, day *db.Day) (string, mod
// selectWorkType updates the day's work type from a callback.
func (h *Handler) selectWorkType(ctx context.Context, chatID int64, msgID int, callbackID, idStr string) {
defer h.Bot.AnswerCallbackQuery(ctx, &bot.AnswerCallbackQueryParams{CallbackQueryID: callbackID})
defer h.answerCb(ctx, callbackID)
_, day, err := h.getUserToday(chatID)
if err != nil {
return
@@ -425,7 +427,7 @@ func (h *Handler) selectWorkType(ctx context.Context, chatID int64, msgID int, c
return
}
kb := backKeyboard()
h.Bot.EditMessageText(ctx, &bot.EditMessageTextParams{ChatID: chatID, MessageID: msgID, Text: fmt.Sprintf("Work type set to: %s", wt.Name), ReplyMarkup: kb})
h.editText(ctx, chatID, msgID, fmt.Sprintf("Work type set to: %s", wt.Name), &kb)
}
// mainKeyboard returns the persistent inline menu.
@@ -472,7 +474,41 @@ func formatDuration(seconds int64) string {
// sendText sends a plain text message to the given chat.
func (h *Handler) sendText(ctx context.Context, chatID int64, text string) {
h.Bot.SendMessage(ctx, &bot.SendMessageParams{ChatID: chatID, Text: text})
if _, err := h.Bot.SendMessage(ctx, &bot.SendMessageParams{ChatID: chatID, Text: text}); err != nil {
slog.Warn("send text failed", "chat_id", chatID, "error", err)
}
}
// editText edits an existing message, logging errors.
func (h *Handler) editText(ctx context.Context, chatID int64, msgID int, text string, kb *models.InlineKeyboardMarkup) {
p := &bot.EditMessageTextParams{ChatID: chatID, MessageID: msgID, Text: text}
if kb != nil {
p.ReplyMarkup = kb
}
if _, err := h.Bot.EditMessageText(ctx, p); err != nil {
slog.Warn("edit text failed", "chat_id", chatID, "msg_id", msgID, "error", err)
}
}
// sendWithKB sends a message with an inline keyboard, logging errors.
func (h *Handler) sendWithKB(ctx context.Context, chatID int64, text string, kb models.InlineKeyboardMarkup) {
if _, err := h.Bot.SendMessage(ctx, &bot.SendMessageParams{ChatID: chatID, Text: text, ReplyMarkup: kb}); err != nil {
slog.Warn("send with keyboard failed", "chat_id", chatID, "error", err)
}
}
// answerCb answers a callback query, logging errors.
func (h *Handler) answerCb(ctx context.Context, callbackID string) {
if _, err := h.Bot.AnswerCallbackQuery(ctx, &bot.AnswerCallbackQueryParams{CallbackQueryID: callbackID}); err != nil {
slog.Debug("answer callback failed", "error", err)
}
}
// answerCbWithText answers a callback query with a toast message, logging errors.
func (h *Handler) answerCbWithText(ctx context.Context, callbackID, text string) {
if _, err := h.Bot.AnswerCallbackQuery(ctx, &bot.AnswerCallbackQueryParams{CallbackQueryID: callbackID, Text: text}); err != nil {
slog.Debug("answer callback with text failed", "error", err)
}
}
// navMonth returns the (prevY, prevM, nextY, nextM) for month navigation.
@@ -493,8 +529,12 @@ func navMonth(year, month int) (prevY, prevM, nextY, nextM int) {
// sendOrEdit sends a new message or edits an existing one depending on msgID.
func (h *Handler) sendOrEdit(ctx context.Context, chatID int64, msgID int, text string, kb *models.InlineKeyboardMarkup) {
if msgID == 0 {
h.Bot.SendMessage(ctx, &bot.SendMessageParams{ChatID: chatID, Text: text, ReplyMarkup: kb})
if kb != nil {
h.sendWithKB(ctx, chatID, text, *kb)
} else {
h.sendText(ctx, chatID, text)
}
} else {
h.Bot.EditMessageText(ctx, &bot.EditMessageTextParams{ChatID: chatID, MessageID: msgID, Text: text, ReplyMarkup: kb})
h.editText(ctx, chatID, msgID, text, kb)
}
}