mirror of
https://github.com/tiennm99/goclaw.git
synced 2026-07-13 09:06:04 +00:00
5040fe4cbe
Rework of #911 against dev with correctness fixes. Public-facing channels (Facebook, Telegram, Discord, Feishu, WhatsApp, Zalo OA, Zalo Personal, Pancake, Slack) no longer receive raw internal error text when an agent run fails — an empty outbound is published instead so channels still clean up placeholders / typing indicators. Errors continue to be logged server-side at Error level. Applied on both hot paths: - cmd/gateway_consumer_normal.go (agent run failure) - cmd/gateway_subagent_announce_queue.go (announce lead run failure) Fixes vs #911: - Whitelist uses channels.Type* constants (compile-time safe) instead of string literals. The original PR's literals ("zalo", "line") did not match any real channel type, so Zalo OA/Personal and Pancake leaked errors while "line" was a dead branch. - Added TypePancake and TypeSlack which were missing. - Empty Content in Facebook.Send and Pancake.Send now short-circuits (matching Telegram/Discord/Slack). Previously, suppressed errors flowed to Graph/Pancake APIs as empty payloads, triggering 400s and channel health degradation. - Added table-driven test for isExternalChannel covering all real channel types + empty + unknown + legacy "zalo" short form. Closes #911
50 lines
1.6 KiB
Go
50 lines
1.6 KiB
Go
package cmd
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/nextlevelbuilder/goclaw/internal/channels"
|
|
)
|
|
|
|
// TestIsExternalChannel ensures the whitelist matches actual channel type
|
|
// constants — a mismatch here silently leaks internal error strings to end
|
|
// users (e.g. "zalo" vs "zalo_oa"/"zalo_personal"). Always compare against
|
|
// channels.Type* constants, never string literals.
|
|
func TestIsExternalChannel(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
cases := []struct {
|
|
name string
|
|
channelType string
|
|
want bool
|
|
}{
|
|
// Public-facing platforms — errors must be suppressed.
|
|
{"facebook", channels.TypeFacebook, true},
|
|
{"telegram", channels.TypeTelegram, true},
|
|
{"discord", channels.TypeDiscord, true},
|
|
{"feishu", channels.TypeFeishu, true},
|
|
{"whatsapp", channels.TypeWhatsApp, true},
|
|
{"zalo_oa", channels.TypeZaloOA, true},
|
|
{"zalo_personal", channels.TypeZaloPersonal, true},
|
|
{"pancake", channels.TypePancake, true},
|
|
{"slack", channels.TypeSlack, true},
|
|
|
|
// Internal / unknown channel types — errors must still surface.
|
|
{"ws", "ws", false},
|
|
{"empty", "", false},
|
|
{"unknown", "myplatform", false},
|
|
// "line" is a Pancake sub-platform, not a top-level channel type.
|
|
{"line_not_top_level", "line", false},
|
|
// Legacy short "zalo" string must NOT match — real constants are zalo_oa / zalo_personal.
|
|
{"zalo_short_form", "zalo", false},
|
|
}
|
|
|
|
for _, tc := range cases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
if got := isExternalChannel(tc.channelType); got != tc.want {
|
|
t.Fatalf("isExternalChannel(%q) = %v, want %v", tc.channelType, got, tc.want)
|
|
}
|
|
})
|
|
}
|
|
}
|