Open travisbrown opened 4 years ago
This is partially addressed by #3361. In the longer run we should consider what to do with attemptNarrow
and catchOnly
(probably we should just add documentation about the risks, but we could also consider deprecation).
I can't find any mentions of this on GitHub so, on the topic of catchOnly
, it's possible to catch fatal exceptions in the sense of scala.util.control.NonFatal
. To me that doesn't feel safe at all.
import cats.data.Validated
def boom = throw new OutOfMemoryError
Validated.catchOnly[Error] { boom } // => Invalid(java.lang.OutOfMemoryError): Validated[Error,Nothing]
Looking at the hierarchy, it looks like the list of problematic type parameters would be limited to fatal exceptions themselves, which is obvious, but also Exception
(due toInterruptedException
), Error
and Throwable
. Anything more specific (including RuntimeException
) wouldn't be a problem afaict.
@travisbrown please consider keeping attemptNarrow
with properly documented risks.
I found this method pretty convenient when you need to temporary put your business error from F[Either[E, A]]
into F[A]
with rethrow
and then later extract it back with attemptNarrow
.
@lukoyanov The current plan I think is to keep it but with a <: Throwable
constraint on E
. Does that affect your use cases?
Does that affect your use cases?
@travisbrown <: Throwable
constraint on E
looks reasonable, perfectly works for me.
Somehow I'd never paid attention to
attemptNarrow
, which we added in 2.1.0. It has some problems. For example it's trivially easy to make it crash at runtime:It can also be used to launder a runtime type check:
Maybe that's fine, and you should know that if you've got a
ClassTag
around you've given up any hope of parametricity, but that seems pretty far from the spirit of Cats.@tpolecat requested tests for the erasure issues in the original PR, but unfortunately the tests that were added don't actually check for the relevant problems.
I guess the reasoning is that
E
is usually an exception type, and generally won't be generic? In any case I think we should make both the type class and syntax methods package-private in future 2.x releases and remove them in 3.0, or at least put an explicit<: Throwable
constraint on them (which doesn't eliminate the possibility of runtime crashes, but does make them much less likely).