Youssef Shoaib [MOD]
03/22/2023, 7:38 PMrunCatching
swallowing `RaiseCancellationException`s and hence not playing nicely with Raise
? Should Arrow maybe offer an alternative runNonFatalCatching
or a Raise.runCatching
shadowed function that rethrows cancellation exceptions?simon.vergauwen
03/23/2023, 8:24 AMrunCatching
swallows CancellationExeption
it also swallows RaiseCancellationException
😞 This is inherit to Result
since it's meant for the intrinsics
of Kotlin Coroutines.
There is a top-level catch
function, and Either.catch
that allow avoiding this issue. We could also add something for Result
🤔 Currently:
val x: Either<Throwable, Int> = Either.catch { 1 }
val y: Either<PSQLException, Int> = Either.catchOrThrow { 1 }
val i: Int = catch({ 1 }) { _: Throwable -> fallback() }
fun Raise<E>.example(): Int =
catch({ 1 }) { _: Throwable -> raise(e) }
fun Raise<E>.example(): Int =
catch({ 1 }) { _: PSQLException -> raise(e) }
Youssef Shoaib [MOD]
03/23/2023, 2:03 PMfun Raise<E>.runCatching(block: () -> R): Result<R>
so that if someone takes pre-existing code that uses runCatching and then wraps some of it in effect
the code would still work. Maybe even with a @Deprecated
that tells them to use Either
instead of Result
simon.vergauwen
03/26/2023, 5:59 PM@Deprecated
with level = Deprecation.ERROR
to prevent incorrect usages 🤔 https://github.com/arrow-kt/arrow/issues/2838
I'm still awaiting FIR to be-able to do add IDEA inspections through a compiler plugin, but that seems quite far away. Building a IDEA plugin seems a bad workaround.Youssef Shoaib [MOD]
03/26/2023, 9:32 PMDeprecation.ERROR
runCatching
function that tells the person to use either. Shall I make a PR for that, and perhaps even for bind errors? Only issue is, I'm not sure how we'd write tests to test that those functions are doing their job correctly...simon.vergauwen
04/02/2023, 5:19 PMrunCatching
inside Raise
that doesn't catch the RaiseCancellationException
but still captures the more general CancellationException
. Or even not catch it at all.
It's possible since it'll prefer the version declared on the receivers, not sure how it would behave with context receivers though.. They fix the problem of scope pollution, but not sure how it works with a function defined on a context vs top-level. I guess it would still prefer the context variant.Youssef Shoaib [MOD]
04/02/2023, 5:25 PMRaiseCancellationException
, and hence every erroneous instance of runCatching { somethingThatUsesRaise() }
will always have a Raise receiver in scope, and any other runCatching
invocation outside of a Raise receiver would never throw RaiseCancellationException
anyways.simon.vergauwen
04/02/2023, 5:26 PMin this case only functions that take a Raise as some form of receiver (extension, dispatch, or context) would ever be able to throw aYes, that was exactly my train of thought, and hence every erroneous instance ofRaiseCancellationException
will always have a Raise receiver in scope, and any otherrunCatching { somethingThatUsesRaise() }
invocation outside of a Raise receiver would never throwrunCatching
anyways.RaiseCancellationException
Youssef Shoaib [MOD]
04/02/2023, 5:26 PMsimon.vergauwen
04/02/2023, 5:27 PMYoussef Shoaib [MOD]
04/02/2023, 5:27 PMfun myStupidFun(raise: Raise<Blah>) = with(raise) { ... }
simon.vergauwen
04/02/2023, 5:27 PMwhile if it was a member of the Raise interface, then it doesn't need to be importedI meant as a member on
Raise
, I thought we already came to the conclusion that was a requirement 😜simon.vergauwen
04/02/2023, 5:28 PMfun myStupidFun(raise: Raise<Blah>) =
runCatching { raise.raise(blah) }
Youssef Shoaib [MOD]
04/02/2023, 5:28 PMcontext(Raise) fun runCatching
simon.vergauwen
04/02/2023, 5:29 PMYoussef Shoaib [MOD]
04/02/2023, 5:29 PMsimon.vergauwen
04/02/2023, 5:30 PM