SessionError events that close a running stream, and synchronous exception classes thrown for API misuse before/during a Stream<SessionEvent> is established. They are aligned across Dart, Kotlin, and Swift.
SessionErrorCode (in-stream)
Wire enum from session.proto:
SessionErrorCode.fromString(value) (all three SDKs) parses the wire string. Unknown values throw ArgumentError in Dart.
SessionError event
SessionError always closes the stream. After it fires, the same sessionId can be started again with a fresh SessionConfig.
message is human-readable and platform-specific. Hosts should log it but should not parse it for control flow β only code is stable.
Recovery paths
Dart synchronous exceptions
For misuse that doesnβt reach the engine, the Dart SDK throws:
These do not reach the event stream β theyβre thrown directly from
SynheartSession.startSession(...) and friends.
Distinguishing the two surfaces
Channel error swallowing
The Watch event channel listener treats channel transport errors as non-fatal β dropped frames during a brief disconnect are preferable to forcing the host to handle aSessionError(osTerminated) for every Bluetooth blip. Apps that need strict reachability semantics must poll getWatchStatus() and stop the session manually on persistent disconnect.
Logging
The SDK does not write to platform log streams beyondassert-guarded print calls. Hosts that need structured logging should subscribe to the Stream<SessionEvent> and log at the call site.
Related
- Lifecycle β when
SessionErrorfires and the resulting state. - Watch Protocol β
ErrorCodeproto enum.