Hello, I’m experimenting with context receivers an...
# arrow
d
Hello, I’m experimenting with context receivers and the
Raise
way of handling errors. When dealing with multiple types of errors, so far there hasn’t been a solution that would allow to declare that a function or a flow can result in X amount of error types (something that Union types would solve). It seems that context receivers might provide a solution for this by declaring multiple
Raise<ErrorT>
contexts. This is fine for functions but it runs short for flows. If a flow can result in either
ErrorA
,
ErrorB
or
Result
, and we don’t want to interrupt it on error, just handle the error value and wait for the next one, then, from my understanding, it looks like we can’t use Raise DSL straight away. So I tried to think of a solution for this and that resulted in creating a custom class that will be used instead of
Raise
and will provide the necessary functions so the flow can use it when it encounters an error. At some point this started to feel like I’m abusing both context receivers and Raise DSL 😅 So is there a recommended way of doing this? Basically if I have a
flow A
(
Flow<String>
, where
ErrorA
can occur) and
flow B
(
Flow<String>
, where
ErrorB
can occur), can I use context receivers to handle both errors when I collect the flow, without introducing a new type (like a sealed class), that would unionize the two errors?
y
You could simply use
either
inside the flows, thus emitting an either, and simply
bind
on the other side. Another way could be to emit functions of the form
context(Raise<Error1>) () -> R
and thus you'd have to
invoke
them on the collecting side. Ideally, there could be some Raise-based flow implementation that deals with all those problems by having its methods need a
Raise
to be called
d
Emitting functions with Raise context was my other guess, but then I won't be able to perform operations on the flow, based on the value (map, filter, etc.) unless I introduce custom versions of the operators that use fold. Using Either would do when a flow can result in a single type of error, but won't do the job if a single flow can emit two or more types of errors. It seems that union types are really what is needed here 😅
y
Union types + a custom flow type that is aware of raise would be the perfect solution here yes
a
another possibility is to create a custom type which implements several
Raise
, to have exactly the bheavior you want
we cover this a bit in the Arrow docs https://arrow-kt.io/learn/typed-errors/own-error-types/
(but not in relation to Flow, though)
c
Is it possible to create a type that implements the same interface multiple times? I thought it wasn't allowed.