From 3093be222258db93270e3ff9a1b0c6d277519127 Mon Sep 17 00:00:00 2001 From: LanQin_ Date: Tue, 16 Jun 2026 15:10:28 +0800 Subject: [PATCH] =?UTF-8?q?fix(mail):=20=E5=8F=91=E9=80=81=E5=A4=B1?= =?UTF-8?q?=E8=B4=A5=E6=97=B6=E8=BF=94=E5=9B=9E=20SMTP=20=E9=94=99?= =?UTF-8?q?=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 发送邮件时若 `SMTP` 投递失败,直接返回 `502 Bad Gateway`。 - 新增测试覆盖投递失败场景,确认错误信息会透出。 --- apps/api/internal/app/app_test.go | 26 ++++++++++++++++++++++++++ apps/api/internal/app/mail_handlers.go | 3 ++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/apps/api/internal/app/app_test.go b/apps/api/internal/app/app_test.go index d8f5e56..41bc943 100644 --- a/apps/api/internal/app/app_test.go +++ b/apps/api/internal/app/app_test.go @@ -589,6 +589,32 @@ func TestCatchAllStoresUnregisteredMailForAdminOnly(t *testing.T) { } } +func TestMailSendReturnsSMTPFailure(t *testing.T) { + a := newTestApp(t) + a.cfg.SMTPHost = "127.0.0.1" + a.cfg.SMTPPort = "1" + ts := httptest.NewServer(a.Router()) + defer ts.Close() + admin := &testClient{t: t, server: ts} + + var login map[string]any + if code := admin.do("POST", "/api/auth/login", map[string]string{"email": "admin@lanqin.local", "password": "ChangeMe123!"}, &login); code != http.StatusOK { + t.Fatalf("login code=%d body=%v", code, login) + } + payload := map[string]any{ + "to": []string{"person@example.com"}, + "subject": "smtp failure should surface", + "text": "hello", + } + var errBody map[string]any + if code := admin.do("POST", "/api/mail/send", payload, &errBody); code != http.StatusBadGateway { + t.Fatalf("smtp failure code=%d body=%v", code, errBody) + } + if got, _ := errBody["error"].(string); !strings.Contains(got, "smtp delivery failed") { + t.Fatalf("error=%q", got) + } +} + func TestAdminSMTPTestEndpoint(t *testing.T) { a := newTestApp(t) host, port, received := startFakeSMTP(t) diff --git a/apps/api/internal/app/mail_handlers.go b/apps/api/internal/app/mail_handlers.go index 31311ce..da13a9b 100644 --- a/apps/api/internal/app/mail_handlers.go +++ b/apps/api/internal/app/mail_handlers.go @@ -330,7 +330,8 @@ func (a *App) handleMailSend(w http.ResponseWriter, r *http.Request) { } if a.cfg.SMTPHost != "" { if err := a.sendSMTP(mb.Address, allRecipients, mimeBytes); err != nil { - a.log.Warn("smtp delivery failed; keeping local sent copy", "error", err) + respondError(w, http.StatusBadGateway, "smtp delivery failed: "+err.Error()) + return } }