Endre Deak
02/25/2021, 8:21 PMResult
class. I’m trying to go through a process which would look like:
• do step 1, if fail then return with an error
• do step 2 using step 1 result, if fail then return with an error
• …
so far what I coded is kind-of ugly:
runCatching { step1() }
.fold(
onFailure = { myCustomError("step1") },
onSuccess = { step1Result ->
runCatching { step2(step1Result) }
.fold(
onFailure = { myCustomError("step2") },
onSuccess = { ...
...
)
I’m pretty sure there’s a better way to do this - any suggestions?nanodeath
02/25/2021, 8:25 PMval result1 = try { step1() } catch (e: Exception) { myCustomError("step1") }
val result2 = try { step2(result1) } catch (e: Exception) { myCustomError("step2") }
but with like a dozen more newlines in there. doesn't use Result but maybe you can say .get()
to force it to throw or something.Orhan Tozan
02/25/2021, 8:44 PMfun <T, R> Result<T>.letIfSuccess(block: (T) -> Result<R>): Result<R> =
when(this) {
is Result.Failure -> this
is Result.Success -> block(this.data)
}
Orhan Tozan
02/25/2021, 8:45 PMOrhan Tozan
02/25/2021, 8:46 PMOrhan Tozan
02/25/2021, 8:47 PMNir
02/25/2021, 8:51 PMrunCatching
Orhan Tozan
02/25/2021, 8:52 PMNir
02/25/2021, 8:54 PMNir
02/25/2021, 8:55 PMNir
02/25/2021, 8:55 PMval r = runCatching {
val x = someFunc().getOrThrow()
val y = someFunc2().getOrThrow()
}
etcNir
02/25/2021, 8:55 PMNir
02/25/2021, 8:56 PMOrhan Tozan
02/25/2021, 8:57 PMOrhan Tozan
02/25/2021, 8:58 PMOrhan Tozan
02/25/2021, 8:59 PMNir
02/25/2021, 9:09 PMNir
02/25/2021, 9:09 PMfold
you don't really need runCatchingOrhan Tozan
02/25/2021, 9:16 PMNir
02/25/2021, 9:16 PMOrhan Tozan
02/25/2021, 9:16 PMNir
02/25/2021, 9:17 PMOrhan Tozan
02/25/2021, 9:18 PMOrhan Tozan
02/25/2021, 9:18 PMNir
02/25/2021, 9:19 PMOrhan Tozan
02/25/2021, 9:20 PMNir
02/25/2021, 9:21 PMOrhan Tozan
02/25/2021, 9:22 PMNir
02/25/2021, 9:23 PMOrhan Tozan
02/25/2021, 9:24 PMNir
02/25/2021, 9:26 PMNir
02/25/2021, 9:26 PMfold
, and then letIfSuccessNir
02/25/2021, 9:26 PMNir
02/25/2021, 9:27 PMNir
02/25/2021, 9:27 PMOrhan Tozan
02/25/2021, 9:28 PMNir
02/25/2021, 9:28 PMNir
02/25/2021, 9:28 PMNir
02/25/2021, 9:29 PMOrhan Tozan
02/25/2021, 9:29 PMNir
02/25/2021, 9:29 PMval x = runCatching {
step2(step1())
}
Nir
02/25/2021, 9:29 PMNir
02/25/2021, 9:29 PMNir
02/25/2021, 9:29 PMNir
02/25/2021, 9:31 PMval x = runCatching {
val first = runCatching { step1() }.getOrElse { // throw custom exception type }
val second = runCatching { step2(first) }.getOrElse { // throw custom exception type }
}
Orhan Tozan
02/25/2021, 9:31 PMAny
? Or is it a supertype of the custom error type and succeasfull path return typeNir
02/25/2021, 9:31 PMNir
02/25/2021, 9:31 PMOrhan Tozan
02/25/2021, 9:33 PMNir
02/25/2021, 9:34 PMNir
02/25/2021, 9:34 PMx
will be a Result, which is what OP wantsOrhan Tozan
02/25/2021, 9:34 PMNir
02/25/2021, 9:35 PMNir
02/25/2021, 9:35 PMOrhan Tozan
02/25/2021, 9:36 PMNir
02/25/2021, 9:36 PMNir
02/25/2021, 9:36 PMEndre Deak
02/25/2021, 10:03 PMmyCustomError
would return with a custom result object indicating the success of the entire process or the failure (at which step and what the issue was).
So if I’m flattening out, what I want to achieve nicely is something like:
data class MyCustomResult(
val code: ResultCode,
// .. details)
val firstRes = runCatching { first() }
if (firstRes.isFailure) {
return MyCustomResult(STEP_1, first.exceptionOrNull())
}
val secondRes = runCatching { second(firstRes.getOrNull()!!) }
if (secondRes.isFailure)
...
...
Nir
02/25/2021, 10:03 PMEndre Deak
02/25/2021, 10:04 PMNir
02/25/2021, 10:04 PMNir
02/25/2021, 10:05 PMNir
02/25/2021, 10:05 PMEndre Deak
02/25/2021, 10:06 PMNir
02/25/2021, 10:06 PMNir
02/25/2021, 10:06 PMNir
02/25/2021, 10:07 PMNir
02/25/2021, 10:07 PMEndre Deak
02/25/2021, 10:08 PMgetOrElse()
returns with Any
Endre Deak
02/25/2021, 10:09 PMrunCatching { first() }
.getOrElse { firstError() }
.let { f -> second(f) }
.getOrElse { ... }
...
won’t work because f
is Any
instead of the result typeNir
02/25/2021, 10:26 PMNir
02/25/2021, 10:26 PMNir
02/25/2021, 10:27 PMNir
02/25/2021, 10:27 PMNir
02/25/2021, 10:30 PMResult
instead of MyCustomResultNir
02/25/2021, 10:30 PMResult
-like machinery in MyCustomResult