Skip to content

Commit 876c22c

Browse files
0xlukclaude
andcommitted
Handle unknown log types gracefully with body passthrough
Bob sends log type 14 which was causing a fatal parse error and infinite reconnect loop. Unknown log types now pass through the raw body as a generic map instead of erroring, making the bridge forward-compatible with new bob log types. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 0077415 commit 876c22c

5 files changed

Lines changed: 54 additions & 6 deletions

File tree

bob-events-bridge/internal/bob/events.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,8 @@ type CustomMessageBody struct {
109109
}
110110

111111
// ParseEventBody unmarshals the raw body JSON into the typed struct for the
112-
// given log type. Returns the typed struct as interface{}. Returns an error if
113-
// the log type is unknown or the body is malformed.
112+
// given log type. Returns the typed struct as interface{}. Unknown log types
113+
// are parsed as a generic map[string]any so they pass through without error.
114114
func ParseEventBody(logType uint32, body json.RawMessage) (interface{}, error) {
115115
if len(body) == 0 {
116116
return nil, nil
@@ -139,7 +139,12 @@ func ParseEventBody(logType uint32, body json.RawMessage) (interface{}, error) {
139139
case LogTypeCustomMessage:
140140
target = &CustomMessageBody{}
141141
default:
142-
return nil, fmt.Errorf("unknown log type: %d", logType)
142+
// Unknown log type — pass through the raw body as a generic map
143+
var m map[string]interface{}
144+
if err := json.Unmarshal(body, &m); err != nil {
145+
return nil, fmt.Errorf("failed to unmarshal body for unknown log type %d: %w", logType, err)
146+
}
147+
return m, nil
143148
}
144149

145150
if err := json.Unmarshal(body, target); err != nil {

bob-events-bridge/internal/bob/events_test.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -179,9 +179,11 @@ func TestParseEventBody_UnknownLogType(t *testing.T) {
179179
body := json.RawMessage(`{"foo": "bar"}`)
180180

181181
result, err := ParseEventBody(999, body)
182-
assert.Nil(t, result)
183-
assert.Error(t, err)
184-
assert.Contains(t, err.Error(), "unknown log type: 999")
182+
require.NoError(t, err)
183+
184+
parsed, ok := result.(map[string]interface{})
185+
require.True(t, ok, "unknown log type should return map[string]interface{}")
186+
assert.Equal(t, "bar", parsed["foo"])
185187
}
186188

187189
func TestParseEventBody_MalformedBody(t *testing.T) {

bob-events-bridge/internal/e2e/e2e_test.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1380,6 +1380,25 @@ func TestE2E_LogType255_CustomMessage(t *testing.T) {
13801380
})
13811381
}
13821382

1383+
func TestE2E_UnknownLogType_Passthrough(t *testing.T) {
1384+
runLogTypeE2ETest(t, logTypeTestCase{
1385+
name: "unknown_log_type_14",
1386+
eventType: 14,
1387+
bobBody: map[string]any{
1388+
"someField": "someValue",
1389+
"anotherField": 42,
1390+
},
1391+
grpcChecks: map[string]any{
1392+
"someField": "someValue",
1393+
"anotherField": float64(42),
1394+
},
1395+
kafkaChecks: map[string]any{
1396+
"someField": "someValue",
1397+
"anotherField": float64(42),
1398+
},
1399+
})
1400+
}
1401+
13831402
// TestE2E_KafkaPublishFailure tests that processor disconnects and retries on Kafka failure
13841403
func TestE2E_KafkaPublishFailure(t *testing.T) {
13851404
mockBob := NewMockBobServer(145, 22000000)

bob-events-bridge/internal/kafka/message.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,10 @@ func TransformEventBody(eventType uint32, body interface{}) (map[string]any, err
9494
"customMessage": b.CustomMessage,
9595
}, nil
9696

97+
case map[string]any:
98+
// Unknown log type — pass through as-is
99+
return b, nil
100+
97101
default:
98102
return nil, fmt.Errorf("unsupported event body type: %T", body)
99103
}

bob-events-bridge/internal/kafka/message_test.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,24 @@ func TestTransformEventBody_CustomMessage(t *testing.T) {
201201
}
202202
}
203203

204+
func TestTransformEventBody_UnknownLogTypePassthrough(t *testing.T) {
205+
body := map[string]any{
206+
"foo": "bar",
207+
"num": float64(42),
208+
}
209+
210+
result, err := TransformEventBody(999, body)
211+
require.NoError(t, err)
212+
213+
expected := map[string]any{
214+
"foo": "bar",
215+
"num": float64(42),
216+
}
217+
if diff := cmp.Diff(expected, result); diff != "" {
218+
t.Errorf("mismatch (-want +got):\n%s", diff)
219+
}
220+
}
221+
204222
func TestTransformEventBody_UnsupportedType(t *testing.T) {
205223
body := struct{ Foo string }{Foo: "bar"}
206224
_, err := TransformEventBody(99, &body)

0 commit comments

Comments
 (0)