SessionErrorCode
Every SDK has a SessionErrorCode enum whose values serialize to the same snake_case strings:
Parsing a wire string: Dart
SessionErrorCode.fromString(value) throws ArgumentError for an unknown value; Swift uses SessionErrorCode(rawValue:), which returns nil; Kotlinβs SessionEvent.fromMap maps an unknown error_code to INVALID_STATE.
The wire format is JSON-style maps (see Watch Protocol); there is no protobuf schema.
In-stream error events
An error event is terminal: no summary follows it. The Swift
AsyncStream and the Dart stream finish after it; the Kotlin SharedFlow does not complete, so collectors stop on it themselves.
message is human-readable and platform-specific. Log it, but donβt parse it for control flow β only code is stable.
Who emits them
Wire key
KotlintoMap() and Swift toDictionary() put the code under error_code. Dart SessionError.toJson() writes it under code, and SessionError.fromJson() reads code, so the Dart decoder does not accept a session_error map that only carries error_code.
Recovery paths
Thrown exceptions
Dart
These are thrown directly from the call, not delivered on the stream.
stopSession with an unknown id does not throw. ingestHsiMetrics and dispose never throw.
Kotlin
SessionError is a sealed Exception with subclasses PermissionDenied, SensorUnavailable, InvalidState, LowBattery, and OsTerminated, each with a code.
Providers throw
SessionError.SensorUnavailable from startStreaming; SynheartSession turns that into a SessionErrorEvent.
Swift
SessionError is an enum (Error) with cases permissionDenied(String), sensorUnavailable(String), invalidState(String), lowBattery(String), and osTerminated(String); code returns the SessionErrorCode.
Distinguishing the two surfaces
Channel error swallowing
In Flutter,WatchBiosignalProvider treats event-channel errors as non-fatal, so a brief disconnect does not end the session. Apps that need strict reachability must poll getWatchStatus() and stop the session themselves.
Logging
The Dart SDK only prints from anassert-guarded block (a failed watch stop command), so release builds print nothing. The Kotlin WatchSessionRelay and HealthConnectBiosignalProvider log warnings with android.util.Log. Hosts that need structured logging should log events at the call site.
Related
- Lifecycle β when the stream ends and what state follows.
- Watch Protocol β the event maps on the wire.