I want to do this: ```try { callSuspendFun1() }...
# coroutines
d
I want to do this:
Copy code
try {
  callSuspendFun1()
} catch (e: Throwable) {
  withContext(<http://Dispatchers.IO|Dispatchers.IO>) {
    callSuspendFun2()
  }
  throw e
}
1. Is there something to watch out for when suspending inside
catch
? 2. Is it better to re-throw as above? what if I place
throw e
inside
withContext
?
s
You will need to consider how you want cancellation to be handled. By default the call to
withContext
will fail immediately on entry if
e
was caused by job cancellation.
withContext
can also fail on exit if the parent coroutine has become cancelled while it was running. In that case the result could differ depending on whether the
throw
is inside or outside.
Aside from cancellation subtleties, I don’t see any issues 👍
d
Great! Thank you!
r
This might just be a problem with the example but why wouldn't you use
finally
for this?
s
finally
will run in all cases, including normal return, whereas
catch
will only run if there’s an exception
r
Yeah, I'm just struggling to imagine the context where you'd want to do something on error (but not consuming the error) other than some kind of cleanup which you'd always want to run
But if that's your use case then go for it
d
My usecase is "optimistic insert": 1. Insert the record in DB 2. Run a network request to make the same change on the server 3. If it fails, remove the record from DB (in
catch
) and report an error (rethrow)
r
This context is pretty important because there are major problems with equating
catch Throwable
with "network request failed" (even ignoring the UX problems of things appearing and disappearing randomly)
As above, this will throw if the coroutine is cancelled, even if it's cancelled after the request has completed successfully and the backend has updated
It'll also throw if you get a parsing error in the response, even if the response was a success
And because it's Throwable it'll also throw if you get a random JVM error which is nothing to do with the response
👍 1
d
Yes, catching specific exception must be done instead, the example below was shortened to the bare minimum to ask the "meat" of the question 🙂
r
In this case you actually removed the "meat" and ended up turning it into a totally different question 🤷
d
Not really, I was interested in possible subtleties of suspending or throwing in
catch
and got answer to that question. How to properly do an "optimistic insert" is another question which I didn't ask, but brought it up only because you were curious on why a suspending side-effect might be desirable in catch.