Skip to content

Commit 4de7580

Browse files
committed
Materialize errors in event flows
Resolves: #516
1 parent 3530209 commit 4de7580

File tree

2 files changed

+25
-2
lines changed

2 files changed

+25
-2
lines changed

src/commonMain/kotlin/org/hildan/chrome/devtools/protocol/ChromeDPConnection.kt

+14-1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ internal class ChromeDPConnection(
3434
private val frames = webSocket.incoming.receiveAsFlow()
3535
.filterIsInstance<Frame.Text>()
3636
.map { frame -> chromeDpJson.decodeFromString(InboundFrameSerializer, frame.readText()) }
37+
.materializeErrors()
3738
.shareIn(
3839
scope = coroutineScope,
3940
started = SharingStarted.Eagerly,
@@ -47,6 +48,7 @@ internal class ChromeDPConnection(
4748
*/
4849
suspend fun request(request: RequestFrame): ResponseFrame {
4950
val resultFrame = frames.onSubscription { sendOrFailUniformly(request) }
51+
.dematerializeErrors()
5052
.filterIsInstance<ResultFrame>()
5153
.filter { it.matchesRequest(request) }
5254
.first() // a shared flow never completes, so this will never throw NoSuchElementException (but can hang forever)
@@ -76,7 +78,7 @@ internal class ChromeDPConnection(
7678
/**
7779
* A flow of incoming events.
7880
*/
79-
fun events() = frames.filterIsInstance<EventFrame>()
81+
fun events() = frames.dematerializeErrors().filterIsInstance<EventFrame>()
8082

8183
/**
8284
* Stops listening to incoming events and closes the underlying web socket connection.
@@ -87,6 +89,17 @@ internal class ChromeDPConnection(
8789
}
8890
}
8991

92+
private fun Flow<InboundFrame>.materializeErrors(): Flow<InboundFrameOrError> =
93+
catch<InboundFrameOrError> { emit(InboundFramesConnectionError(cause = it)) }
94+
95+
private fun Flow<InboundFrameOrError>.dematerializeErrors(): Flow<InboundFrame> =
96+
map {
97+
when (it) {
98+
is InboundFramesConnectionError -> throw it.cause
99+
is InboundFrame -> it
100+
}
101+
}
102+
90103
/**
91104
* An exception thrown when an error occurred during the processing of a request on Chrome side.
92105
*/

src/commonMain/kotlin/org/hildan/chrome/devtools/protocol/ChromeDPFrames.kt

+11-1
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,20 @@ data class RequestFrame(
3333
val sessionId: String? = null,
3434
)
3535

36+
/**
37+
* General interface represent both real incoming .
38+
*/
39+
internal sealed interface InboundFrameOrError
40+
41+
/**
42+
* Represents errors in the incoming frames flow.
43+
*/
44+
internal class InboundFramesConnectionError(val cause: Throwable) : InboundFrameOrError
45+
3646
/**
3747
* A generic inbound frame received from the server. It can represent responses to requests, or server-initiated events.
3848
*/
39-
internal sealed class InboundFrame {
49+
internal sealed class InboundFrame : InboundFrameOrError {
4050
/** The session ID of the target concerned by this event. */
4151
abstract val sessionId: SessionID?
4252
}

0 commit comments

Comments
 (0)