Skip to content

Commit a271d96

Browse files
committed
fix(telemetry): use pointer indirection for identity transport callback
Avoids capturing OnGotrueID by value at GetSupabase() init time, which would silently hold nil if clientOnce.Do ran before PersistentPreRunE set the callback. Transport now holds &OnGotrueID and dereferences at call time, decoupling initialization order.
1 parent 42b28cd commit a271d96

3 files changed

Lines changed: 27 additions & 7 deletions

File tree

internal/utils/api.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ func GetSupabase() *supabase.ClientWithResponses {
127127
}
128128
transport := &identityTransport{
129129
RoundTripper: http.DefaultTransport,
130-
onGotrueID: OnGotrueID,
130+
onGotrueID: &OnGotrueID,
131131
}
132132
apiClient, err = supabase.NewClientWithResponses(
133133
GetSupabaseAPIHost(),

internal/utils/identity_transport.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,16 @@ const HeaderGotrueID = "X-Gotrue-Id"
66

77
type identityTransport struct {
88
http.RoundTripper
9-
onGotrueID func(string)
9+
onGotrueID *func(string)
1010
}
1111

1212
func (t *identityTransport) RoundTrip(req *http.Request) (*http.Response, error) {
1313
resp, err := t.RoundTripper.RoundTrip(req)
1414
if err != nil {
1515
return resp, err
1616
}
17-
if id := resp.Header.Get(HeaderGotrueID); id != "" && t.onGotrueID != nil {
18-
t.onGotrueID(id)
17+
if id := resp.Header.Get(HeaderGotrueID); id != "" && t.onGotrueID != nil && *t.onGotrueID != nil {
18+
(*t.onGotrueID)(id)
1919
}
2020
return resp, err
2121
}

internal/utils/identity_transport_test.go

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,15 @@ import (
99

1010
func TestIdentityTransport_CapturesGotrueIdHeader(t *testing.T) {
1111
var captured string
12+
cb := func(id string) { captured = id }
1213
transport := &identityTransport{
1314
RoundTripper: roundTripFunc(func(req *http.Request) (*http.Response, error) {
1415
return &http.Response{
1516
StatusCode: 200,
1617
Header: http.Header{"X-Gotrue-Id": []string{"user-abc-123"}},
1718
}, nil
1819
}),
19-
onGotrueID: func(id string) { captured = id },
20+
onGotrueID: &cb,
2021
}
2122
req, _ := http.NewRequest("GET", "https://api.supabase.io/v1/projects", nil)
2223
resp, err := transport.RoundTrip(req)
@@ -27,14 +28,15 @@ func TestIdentityTransport_CapturesGotrueIdHeader(t *testing.T) {
2728

2829
func TestIdentityTransport_IgnoresWhenHeaderMissing(t *testing.T) {
2930
var captured string
31+
cb := func(id string) { captured = id }
3032
transport := &identityTransport{
3133
RoundTripper: roundTripFunc(func(req *http.Request) (*http.Response, error) {
3234
return &http.Response{
3335
StatusCode: 200,
3436
Header: http.Header{},
3537
}, nil
3638
}),
37-
onGotrueID: func(id string) { captured = id },
39+
onGotrueID: &cb,
3840
}
3941
req, _ := http.NewRequest("GET", "https://api.supabase.io/v1/projects", nil)
4042
_, err := transport.RoundTrip(req)
@@ -58,13 +60,31 @@ func TestIdentityTransport_NilCallbackDoesNotPanic(t *testing.T) {
5860
assert.Equal(t, 200, resp.StatusCode)
5961
}
6062

63+
func TestIdentityTransport_NilFuncBehindPointerDoesNotPanic(t *testing.T) {
64+
var cb func(string) // nil func
65+
transport := &identityTransport{
66+
RoundTripper: roundTripFunc(func(req *http.Request) (*http.Response, error) {
67+
return &http.Response{
68+
StatusCode: 200,
69+
Header: http.Header{"X-Gotrue-Id": []string{"user-abc-123"}},
70+
}, nil
71+
}),
72+
onGotrueID: &cb,
73+
}
74+
req, _ := http.NewRequest("GET", "https://api.supabase.io/v1/projects", nil)
75+
resp, err := transport.RoundTrip(req)
76+
assert.NoError(t, err)
77+
assert.Equal(t, 200, resp.StatusCode)
78+
}
79+
6180
func TestIdentityTransport_InnerTransportError(t *testing.T) {
6281
var captured string
82+
cb := func(id string) { captured = id }
6383
transport := &identityTransport{
6484
RoundTripper: roundTripFunc(func(req *http.Request) (*http.Response, error) {
6585
return nil, assert.AnError
6686
}),
67-
onGotrueID: func(id string) { captured = id },
87+
onGotrueID: &cb,
6888
}
6989
req, _ := http.NewRequest("GET", "https://api.supabase.io/v1/projects", nil)
7090
resp, err := transport.RoundTrip(req)

0 commit comments

Comments
 (0)