Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions platform-api/internal/server/overrides.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"log/slog"
"net/http"
"sort"
"strings"

"github.com/wso2/api-platform/platform-api/internal/router"
)
Expand Down Expand Up @@ -56,10 +57,13 @@ func installCoreRoutes(
}
if len(unknown) > 0 {
sort.Strings(unknown)
p := unknown[0]
return fmt.Errorf("plugin %q declared a route override for %q, which is not a core route "+
"(patterns are matched exactly, including method and path; %d override(s) unmatched)",
overrides[p].plugin, p, len(unknown))
claims := make([]string, 0, len(unknown))
for _, pattern := range unknown {
claims = append(claims, fmt.Sprintf("plugin %q -> %q", overrides[pattern].plugin, pattern))
}
return fmt.Errorf("%d route override(s) name a pattern that is not a core route "+
"(patterns are matched exactly, including method and path): %s",
len(unknown), strings.Join(claims, "; "))
}

// A duplicate pattern can now only come from a plugin route registered on
Expand Down
36 changes: 36 additions & 0 deletions platform-api/internal/server/overrides_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,42 @@ func TestInstallCoreRoutes_UnknownPatternAbortsStartup(t *testing.T) {
}
}

// One unmatched pattern per error would mean fixing a typo, restarting, and
// finding the next one — so the error names every unmatched override at once.
func TestInstallCoreRoutes_UnknownPatternErrorNamesEveryOverride(t *testing.T) {
patterns := []string{
"GET /api/v1/gateways/{gatewayId}",
"GET /api/v0.9/gateways/{id}",
"POST /api/v0.9/gateways",
}
cloud := &overridePlugin{
fakePlugin: &fakePlugin{name: "cloud", spec: specWithScopes},
overrides: []pdk.RouteOverride{
{Pattern: patterns[0], Wrap: passthrough},
{Pattern: patterns[1], Wrap: passthrough},
},
}
audit := &overridePlugin{
fakePlugin: &fakePlugin{name: "audit", spec: specWithScopes},
overrides: []pdk.RouteOverride{{Pattern: patterns[2], Wrap: passthrough}},
}

_, err := startup(t, coreRecorder(map[string]int{}), cloud, audit)
if err == nil {
t.Fatal("expected startup to abort, got nil error")
}
for _, pattern := range patterns {
if !strings.Contains(err.Error(), pattern) {
t.Fatalf("error should name every unmatched pattern, %q missing from: %v", pattern, err)
}
}
for _, plugin := range []string{"cloud", "audit"} {
if !strings.Contains(err.Error(), plugin) {
t.Fatalf("error should name every claiming plugin, %q missing from: %v", plugin, err)
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
}
}

// Two decorators on one route would have to be ordered by something no plugin
// author can see, so this is a startup error naming both claimants.
func TestInitPlugins_TwoPluginsClaimingOnePatternAbortStartup(t *testing.T) {
Expand Down
Loading