Hi all, I’m new to arrows. My use case is if an ex...
# arrow
p
Hi all, I’m new to arrows. My use case is if an exception occurs in a function, then I want to catch it and do some post processing, something like this:
Copy code
fun f1(): Either<Throwable, String> {
	either {
		doSomething() //throws exception
	}
}

fun f2() {
	f1().fold(
		{
			print("you messed up")
            doErrorHandling()
		},
		{
			print("everything's fine")
		}
	)
}

fun main() {
	runCatching{
		f2()
	}
	.onSuccess {
		print("it worked")
	}
	.onFailure {
		print("Either didn't catch exception")
	}
}
When function f1() throws exception here, the code should print “you messed up” but instead it’s printing “Either didn’t catch exception”. Am I doing anything wrong here? I’m using kotlin 1.7.0 and arrow version 1.1.2 TIA
s
for code that throws you can use
Either.catch {}
or similar functions e.g.
Copy code
Either.catch { doSomething() }
p
@stojan had tried it as well, but it wasn’t working as I intended to. Output was same as the either block
a
@Partho Paul what did you try exactly? I often find the combination of
Either.catch
within an
either
block a bit confusing
you either remove the block altogether
Copy code
fun f1(): Either<Throwable, String> =
	Either.catch { doSomething() }
or you need to call
bind
to make the block aware of the thing being run
Copy code
fun f1(): Either<Throwable, String> {
	either {
		Either.catch { doSomething() }.bind()
	}
}
p
@Alejandro Serrano Mena I had tried the below approach with Either.catch:
Copy code
fun f1(): Either<Throwable, String> {
	Either.catch {
		doSomething() //throws exception
	}
}

fun f2() {
	f1().fold(
		{
			print("you messed up")
            doErrorHandling()
		},
		{
			print("everything's fine")
		}
	)
}

fun main() {
	runCatching{
		f2()
	}
	.onSuccess {
		print("it worked")
	}
	.onFailure {
		print("Either didn't catch exception")
	}
}
a
note that above you are "throwing away" the either, you need to define it as
Copy code
fun f1(): Either<Throwable, String> =
	Either.catch { doSomething() }
(note that I'm using
=
and not braces)
☝️ 3
p
@Alejandro Serrano Mena Tried using
Copy code
fun f1(): Either<Throwable, String> =
	Either.catch { doSomething() }
but still not able to catch exception in f2
p
@stojan Thanks, this helps. The Exception I was getting from f1 was LinkageError which is fatal. Tested the code with other non fatal exceptions as per @Alejandro Serrano Mena’s suggestion and it was working.
r
@Partho Paul I’m curious about the use case to capture a fatal ex. like in this case
LinkageError
, how did you plan to recover from it? and what leads you to this point where you care about it in user code?
p
@raulraja So for me, f1() was a db call. In my use case, I’m trying to fetch a document from db and do some action based on the data received. If I don’t receive any data or the db call fails because of any exception, then I’ll perform another set of actions. I wasn’t aware that the sdk which I’m using inside f1() will return fatal exception as the error message was misleading. Currently I don’t have anything planned for recovering from this
LinkageError
. I’m migrating a legacy codebase into a new microservice. I’ll discuss it with my colleagues if we should continue the earlier workflow or short-circuit the process. I’ll be in favour of short-circuiting as continuing the earlier workflow will make the system less reliable.
👍 2
r
The reason I was asking is because
LinkageError
is fatal and usually means you are missing a native library file in the path and your application should not even be running at that point. Exceptions would be some kind of local application where the user is responsible to provide the linked libraries manually but that is an odd case. Normally you can’t recover from fatal exceptions because at that point for many of them you don’t even have guarantees the VM is in a recoverable state, for example
OutOfMemoryError
👍 2