Skip to content

WebSocket/SignalR interceptors: connection.errors array mutated in place #129

Description

@tyevco

Summary

The WebSocket and SignalR interceptors mutate the `connection.errors` array in place using `.push()`, then pass the same array reference to `updateConnection()`. While this works correctly for the interceptor's internal state (which uses mutable objects in a Map), it could cause issues if any consumer relies on reference equality to detect changes.

Affected Files

`plugins/websocket-signalr-devtools/src/core/signalr-interceptor.ts`

Lines 183-186, 234, 286, 361:
```typescript
connection.errors.push(errorObj);
if (connection.errors.length > 100) {
connection.errors = connection.errors.slice(-100);
}
```

`plugins/websocket-signalr-devtools/src/core/websocket-interceptor.ts`

Lines 292-295:
```typescript
connection.errors.push(error);
if (connection.errors.length > 100) {
connection.errors = connection.errors.slice(-100);
}
```

Design Decision

The interceptors use mutable internal state (Map of connection objects), which is appropriate for their role as data collectors. The `updateConnection` method uses `Object.assign(connection, updates)` which is consistent with the mutable pattern.

However, if a downstream store or React component compares the errors array by reference (e.g., in a `useMemo` dependency or a shallow equality check), it would miss updates because:

  • `.push()` mutates the existing array (same reference)
  • `.slice(-100)` creates a new array (new reference), but only when the cap is hit

Suggested Fix (if needed)

Always create a new array to ensure reference changes are detectable:
```typescript
connection.errors = [...connection.errors, errorObj].slice(-100);
```

Priority

Low — the interceptors emit events with the update data, so downstream consumers typically receive the data through events rather than comparing array references.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions