Edgar Avuzi
05/02/2025, 6:10 AMEdgar Avuzi
05/02/2025, 6:12 AMCommand.EVALUATE -> {
val expr = parseTokens(tokens, errors)
val either = either { interpreter.evaluate(expr) }
when (either) {
is Either.Left -> {
System.err.println(either.value.message)
System.err.println("[line ${either.value.lineNumber}]")
exitProcess(70)
}
is Either.Right -> either.value.toLoxString().let { println(it) }
}
}
need to get stacktrace in Either.Left
branchYoussef Shoaib [MOD]
05/02/2025, 6:19 AMtraced
Raise
builderEdgar Avuzi
05/02/2025, 6:38 AMCommand.EVALUATE - > {
val expr = parseTokens(tokens, errors)
val either =
either {
traced(
block = {
interpreter.evaluate(expr)
},
trace = { trace, error - >
println("Trace: $trace")
},
)
}
when(either) {
is Either.Left - > {
System.err.println(either.value.message)
System.err.println("[line ${either.value.lineNumber}]")
exitProcess(70)
}
is Either.Right - > either.value.toLoxString().let {
println(it)
}
}
}
?
Strange it gives
Trace: Trace(exception=arrow.core.raise.Traced: kotlin.coroutines.cancellation.CancellationException should never get swallowed. Always re-throw it if captured.This swallows the exception of Arrow's Raise, and leads to unexpected behavior.When working with Arrow prefer Either.catch or arrow.core.raise.catch to automatically rethrow CancellationException.)
Youssef Shoaib [MOD]
05/02/2025, 6:41 AMprintStackTrace
and other similar methods to get the stack trace you wantEdgar Avuzi
05/02/2025, 6:47 AMprintln("Trace: ${trace.stackTraceToString()}")
gives me stacktraceYoussef Shoaib [MOD]
05/02/2025, 6:55 AMtraced
is that it doesn't have an obvious way to combine the error with the stack trace and have that be raised instead. I'm pretty sure, though, that you can just do:
public inline fun <Error, OtherError, A> Raise<Error>.withErrorTraced(
transform: (Trace, OtherError) -> Error,
block: Raise<OtherError>.() -> A
): A {
contract {
callsInPlace(block, EXACTLY_ONCE)
}
withError({ _: OtherError -> error("should never be called") }) {
traced({ return block(this) }) { trace, error -> raise(transform(trace, error)) }
}
}
simon.vergauwen
05/02/2025, 8:04 AMTrace
to be a data class
and include the Error
..
That is a source compatible change, but a binary breaking one. In this case I think it's okay as long as it's across a minor versionYoussef Shoaib [MOD]
05/02/2025, 8:05 AMwithErrorTraced
the primitive and traced
an instance of itsimon.vergauwen
05/02/2025, 8:21 AMEdgar Avuzi
05/06/2025, 2:37 PMwithErrorTraced
is to be able to handle both error and Trace in Either.Left
branch?
val expr = parseTokens(tokens, errors)
val either: Either < InterpreterErrorWithTrace, Any ? > =
either {
withErrorTraced(
transform = { trace, interpreterError - >
InterpreterErrorWithTrace(
interpreterError = interpreterError,
trace = trace
)
}
) {
interpreter.evaluate(expr)
}
}
when(either) {
is Either.Left - > {
System.err.println(either.value.interpreterError.message)
System.err.println("[line ${either.value.interpreterError.lineNumber}]")
System.err.println("Trace: ${either.value.trace.stackTraceToString()}")
exitProcess(70)
}
is Either.Right - > {
println(either.value.toLoxString())
}
}
seems like this works for me