Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

["Request"] Improve stacktracer for Exceptions thrown from either and either.eager #2647

Closed
danitutu opened this issue Jan 17, 2022 · 6 comments

Comments

@danitutu
Copy link

danitutu commented Jan 17, 2022

Arrow version: 1.0.1

When an exception is thrown inside an either or either.eager.

The exception loses the information about the place it was thrown.

My guess is that it's because of kotlin inlining.

Is there any way we can keep the stacktrace containing the line numbers of the stacktrace calls?

Here's an example:

package com.x

import arrow.core.Either
import arrow.core.computations.either
import org.junit.jupiter.api.Test

class T {
    @Test
    fun myTest() {
        MyClass.aFun()
    }
}

object MyClass {
    fun aFun(): Either<String, Unit> = either.eager {
        println("c")
        bFun()
    }
    fun bFun(): Either<String, Unit> = either.eager {
        println("a")
        println("b")
        throw RuntimeException("the exception")
    }
}

The exception (look mostly at the top):

the exception
java.lang.RuntimeException: the exception
	at com.x.MyClass$bFun$$inlined$eager$1.invokeSuspend(Effect.kt:28)
	at com.x.MyClass$bFun$$inlined$eager$1.invoke(Effect.kt)
	at com.x.MyClass$bFun$$inlined$eager$1.invoke(Effect.kt)
	at arrow.continuations.generic.DelimContScope.invoke(DelimContScope.kt:91)
	at arrow.continuations.Reset.restricted(Reset.kt:37)
	at com.x.MyClass.bFun(Test.kt:28)
	at com.x.MyClass$aFun$$inlined$eager$1.invokeSuspend(Effect.kt:27)
	at com.x.MyClass$aFun$$inlined$eager$1.invoke(Effect.kt)
	at com.x.MyClass$aFun$$inlined$eager$1.invoke(Effect.kt)
	at arrow.continuations.generic.DelimContScope.invoke(DelimContScope.kt:91)
	at arrow.continuations.Reset.restricted(Reset.kt:37)
	at com.x.MyClass.aFun(Test.kt:26)
	at com.x.T.myTest(Test.kt:10)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
...

The line from the exception are either missing or are numbers that do not identify the lines that are being executed.

Without using either or either.eager:

    fun aFun(): Either<String, Unit> {
        println("c")
        return bFun()
    }
    fun bFun(): Either<String, Unit> {
        throw RuntimeException("the exception")
    }
}
the exception
java.lang.RuntimeException: the exception
	at com.x.MyClass.bFun(Test.kt:19)
	at com.x.MyClass.aFun(Test.kt:16)
	at com.x.T.myTest(Test.kt:9)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

As you can see the code clearly states the stacktrace lines.

It's easier to try in the IDE, click the class name and see where it points to.

@raulraja
Copy link
Member

Hi @danitutu, do you have a minimal repro example and the full stack trace?. We can check if we can improve it or if this is an issue to be raised in the kotlin issue tracker.

@danitutu
Copy link
Author

@raulraja Initial description updated.

@nomisRev
Copy link
Member

I wonder if we an improve this by implementing the CoroutineStackFrame interface. I'm wondering if we can re-use the mechanism of rewriting stack traces that is already existing in Kotlin, or does it not work for use-cases like this 🤔

@nomisRev
Copy link
Member

Update with comment from Slack:

This is code generated by the Kotlin compiler, and not sure if we can do something about it inside Arrow. It's an issue inherited by the Kotlin compiler afaik.
https://discuss.kotlinlang.org/t/kotlin-coroutines-stack-trace-problem/23847/3
There are some community work arounds that you can use but haven't tested.
https://github.com/Anamorphosee/stacktrace-decoroutinator

@nomisRev
Copy link
Member

nomisRev commented Apr 5, 2023

This should be solved with the new Raise based DSL, and for Raise errors can also be traced with the new traced API.

@nomisRev nomisRev closed this as completed Apr 5, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants