Repository navigation
Improve safety of attempt & onErrorHandleWith - #566
Conversation
Codecov Report
@@ Coverage Diff @@
## master #566 +/- ##
==========================================
+ Coverage 90.56% 90.67% +0.11%
==========================================
Files 369 369
Lines 9782 9802 +20
Branches 1858 1840 -18
==========================================
+ Hits 8859 8888 +29
+ Misses 923 914 -9 |
That's not an inconsistency. It's a bug Unfortunately such bugs are easy when using inner functions and it's hard to test for it in this case. |
|
About this: Suspend(IO.raiseError(ex1), IO.raiseError(ex2)).onErrorHandleWith { ex =>
/* is ex == ex1 or ex == e2 ? */
}We can't swallow the one in This is a different situation to |
|
FYI — I am fixing |
Including entire #563? |
|
@alexandru I don't return raiseError 😛. As my Iterant, I have a Fix for |
|
@Avasil not the entire issue, if you want you can take care of the others. Was thinking to put into practice my |
|
@oleg-py that's a tough call — prefer |
|
Created the PR - https://github.com/monix/monix/pull/567/files |
|
|
||
| /** Implementation for `Iterant.attempt`. */ | ||
| def attempt[F[_], A](fa: Iterant[F, A])(implicit F: Sync[F]): Iterant[F, Either[Throwable, A]] = { | ||
| type ErrOrA = Either[Throwable, A] |
There was a problem hiding this comment.
We usually call this type Attempt.
There was a problem hiding this comment.
👍 (and a much better name :)
| } | ||
| } | ||
|
|
||
| test("attempt & onErrorHandleWith should protect against broken continuations") { _ => |
There was a problem hiding this comment.
You probably have repetitive code, but this test should be broken in two, because when it fails in Travis, it would be good to know which of them failed, attempt or onErrorHandleWith.
There was a problem hiding this comment.
I hope it's okay if I just extract common code to a method? 😏
| } | ||
|
|
||
| def tailGuard(ffa: F[Iterant[F, A]]): F[Iterant[F, A]] = | ||
| ffa.handleError(f) |
There was a problem hiding this comment.
PS: gone ahead and opened a ticket for a transformWith in MonadError, fingers crossed — typelevel/cats#2161
We can't wait for it though. It will be ages before that happens, if at all 😀
There was a problem hiding this comment.
That won't hurt. In the meantime, I think, users will appreciate correctness anyway 😄
attempt & onErrorHandle
10000
Withattempt & onErrorHandleWith
|
Ok, that should be it. I decided not to use the |
There was a problem hiding this comment.
You made the right decision in not doing the var optimization — it's very risky, because Iterant is served piecemeal, which means that the effects of such a var can end up exposed to the user.
And even though F[_] values in Iterant are supposed to be side effectful on evaluation, we should abstain from side effects that can take the user by surprise.
| try fa match { | ||
| case Next(a, lt, stop) => | ||
| Next(a, lt.map(loop), stop) | ||
| Next(a, tailGuard(stop)(lt.map(loop)), stop) |
There was a problem hiding this comment.
Everything looks good except that I feel this call is overreaching. It should probably not include the .map(loop):
tailGuard(lt, stop).map(loop)For one this is because it's unnecessary and also because we're avoiding optimization opportunities — e.g. lt could be a pure value for which the F[_] implementation could bypass error handling.
|
@oleg-py is there some channel to reach you? Can we chat on Gitter? 😀 |
|
I moved |
|
Thanks @oleg-py |
Closes #562.
I went ahead and made
attemptsafer too.Incorporates tests from #559 comments and my latest work on
bracketTODO:
earlyStopin guards@alexandru should
earlyStopbe called if the evaluation oftailresults on error? (I suppose it should).I noticed some inconsitency that seems to not match my understanding of
earlyStop:Notice that it calls
source.earlyStop. But in your comment for #559 you said:and in this implementation the latest reference would be
self.earlyStop. Most other operators name parameter inside loopsourceinstead ofself, shadowing the one thatapplyaccepts, so they use latestearlyStop. Is that a bug?Another question is the one I raised a number of times already 😄 .
I assume per discussion in typelevel/cats-effect#113 we are going to swallow the one in earlyStop (which is akin to
release), and ther 8000 e's nowhere it can go.