I have an issue with kotlin `Result` and AOP ```p...
# spring
t
I have an issue with kotlin
Result
and AOP
Copy code
package com.example.demo

import org.aspectj.lang.ProceedingJoinPoint
import org.aspectj.lang.annotation.Around
import org.aspectj.lang.annotation.Aspect
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
import org.springframework.stereotype.Component
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RequestParam
import org.springframework.web.bind.annotation.RestController

@SpringBootApplication
class DemoApplication

fun main(args: Array<String>) {
	runApplication<DemoApplication>(*args)
}

@RestController
@RequestMapping("/test")
class TestController(val repository: TestRepository) {
	@GetMapping
	fun test(@RequestParam(defaultValue = "#{{}}") list: List<Int>) =
		repository.getList(list)
				.getOrElse { list }
}

@Component
class TestRepository {
	fun getList(list: List<Int>): Result<List<Int>> = runCatching { throw RuntimeException("Error") }
}

@Aspect
@Component
open class MyOhMy {
	@Around("within(com.example.demo..*Repository+)")
	fun aspect(joinPoint: ProceedingJoinPoint): Any? =
			joinPoint.runCatching {
				proceed()
			}.getOrThrow()
}
issue is that
getOrThrow
in the aspect actually throws, while I would expect to return a
Result<Failure
more in thread
I would expect the above code to work like
Copy code
val result = runCatching { throw RuntimeException("test") }
val wrap = runCatching { result }
println(wrap.getOrThrow())
println(result.getOrNull())
but I think something in
ProceedingJoinPoint
messes up with my expectation
d
Hey @thanksforallthefish -
Copy code
Returns the encapsulated value if this instance represents success or throws the encapsulated exception if it is failure.
This function is shorthand for getOrElse { throw it } (see getOrElse).
there is nothing wrong with the
PJP
t
@Dibya Ranjan thanks for the answer. I forgot to actually write down new findings here, but I think it has to do with mangling: https://github.com/Kotlin/KEEP/blob/master/proposals/inline-classes.md#mangling a similar case: https://youtrack.jetbrains.com/issue/KT-34437 what I meant was, that with
Copy code
joinPoint.runCatching { proceed() }.getOrThrow()
my expectation was to a
<Result<Result<…>>
, where
Result<…>
is a
Failure
, but I think because of mangling (which fyi is not superclear to me), that gets unwrapped and I get
Result<…>
and then ofc
getOrThrow
throws
you can try the small snippet Marco Davi  [3:54 PM] I would expect the above code to work like
Copy code
val result = runCatching { throw RuntimeException("test") }
val wrap = runCatching { result }
println(wrap.getOrThrow())
println(result.getOrNull())
in this example
wrap.getOrThrow
does not throw the exception (as expected)
d
trying
Aren’t these two code equivalent?
Copy code
val result = runCatching { throw RuntimeException("test") }
val wrap = runCatching { result }
println(wrap.getOrThrow())
println(result.getOrNull())
to
Copy code
val x = runCatching {
        runCatching { throw RuntimeException("Failed") }
    }
    println(x.getOrThrow())
    println(x.getOrNull())
I don’t see
.getOrThrow()
called on
val result = runCatching { throw RuntimeException("test") }
. 🤔
t
I have
val result: Result<…>
and
val wrap: Result<Result<…>>
, you have only
val x: Result<Result<…>>
the only difference should be that
println(result.getOrNull()) //prints null
while
println(x.getOrNull()) //prints something else
the point is that
runCatching { result }
is equivalent to
Result.success(result)
, so calling
getOrSomething
should return
result
(and it does, until that code in used in PJP, then mangling(?) messes things up)