Is there a tl;dr for which situations the Arrow pl...
# arrow
k
Is there a tl;dr for which situations the Arrow plugin notifies you when a raise context is leaky?
c
Do you mean: • "In which cases does the plugin notify you?" • "What does it mean that the context is leaky?"
a
The Arrow plug-in for IntelliJ contains one such inspection https://arrow-kt.io/community/blog/2024/06/01/intellij-plugin/
k
@CLOVIS if you could answer both questions that’ll be appreciated!
c
I believe Alejandro has answered the first one; with regards to the second one:
either {}
,
nullable {}
etc introduce a
Raise<>
receiver. But that receiver doesn't actually do much. How it works "for real" is that the builder has a
try … catch
on a specific exception, and
Raise.raise
throws the exact exception the
try … catch
expects. This is how raise can "communicate" with the caller, and short-circuit the code. [It's a bit more complex than that for performance/… reasons, but that's not important]. So, you can imagine that
Copy code
either {
    raise("foo")
}
becomes something like
Copy code
try {
    throw ASpecificException("foo")
} catch (e: ASpecificException)
Now, what happens if you try to use the
raise
function outside of the DSL? Imagine we write:
Copy code
lateinit var r: Raise<String>
either {
    r = this
}
r.raise("foo")
This is a leaking raise: the
Raise
is "leaked" outside of the builder that created it. You can imagine it gets compiled to something like:
Copy code
lateinit var r: Raise<String>
try {
    r = …
} catch (ASpecificException) { … }
throw ASpecificException("foo")
As you can see, the internal exception is now thrown outside of the try-catch, so it can't be caught by the builder, and now you have a weird exception moving around 😅
k
Thanks, that does make sense. I was going through the Raise implementation. I just hadn’t put 2 and 2 together -_-
c
No problem, it's a bit weird 🙂 This is a really common "leak" in Kotlin DSLs, even if they don't use exceptions. For example,
FlowCollector
(the receiver of
flow {}
) has the same problem, but for completely different reasons. In general, objects given to you in a DSL as receiver are really only meant to be used from within the DSL, and if you use them outside, strange stuff can happen.
p
This reminds me we were getting some false positives (in a way, true positives but with no impact) when using a non inline logger that takes a lambda ala
<http://log.info|log.info> { "msg" }
a
May you open an issue in the repo? I think I have an idea of how to improve it, but I didn’t implement it at first because I didn’t know of a real case
p
most assuredly 😄