I am experimenting with the new `runCatching` feat...
# language-proposals
l
I am experimenting with the new
runCatching
feature and I am thinking about this use case: You want to process a list of files and after that you want to do a report about which file names succeeded and which didn't + what was the failure cause for each of them (or maybe possibly group failed file names by the same error etc.). Since now the Failure class contains only the exception, you lose the information for which original value it failed. Would it be possible to extend the Failure class to contain the failed value as well or is there a better way how to solve this use case?
Also it would be nice to have some helper extension functions on collection types, for example:
mapSuccessful()
which could do
mapNotNull { it.getOrNull() }
etc.
g
Just map List<File> to List<Pair<File, SuccessOrFailure>> (or Map) if you want to save relations between File and result
I don't think that it make sense to extend SuccesaOrFailure itself for this, especially because Success OrFailure is inline class and has only one property
Another solution: save value to exception
l
Alright, but what I meant was extending the Failure class only, which is not an inline one, I think.
g
But there is no Failure class, only Throwable. You cannot specify Throwable type now for SuccessOrFailure This is really long discussion about this, some voted for Either type instead, you can check KEEP discussion and original issue: https://github.com/Kotlin/KEEP/issues/127 https://youtrack.jetbrains.com/issue/KT-18608
But anyway even with Either you need own custom class for such use cases to save some error info and some original data. But you can easily achive it now with SuccessAndFailure using pair
val results: List<Pair<File, SuccessOrFailure>> = listOf<File>(…).map { it to runCatching { doSomethingWith(it) } }
l
I am not sure I understand the part that there is no Failure class, because I can see it right there 🙂. The discussion is "too long to read" for me 😄 , so if it has been already considered there to enhance the Failure as Failure<T> containing both Exception and the value + implied change that onFailure {} won't pass Throwable as 'it', but whole Failure<T> (+ other changes, e.g. exceptionOrNull() would have to be failureOrNull() etc.), then I would probably go with the Pair solution as you suggested 🙂.
g
I see, it’s different from original example of proposed implementation. Still I don’t see how you can add “value” to this class, it’s just too narrow use case that makes usage of Failure is not so pleasant (one more generic that not really needed in most cases, usually you just don’t have any
value
, because it’s result of some operation and you not always have value as argument)
l
This is a case where you should use your custom class or a construct like Pair or Map to map the values to their SuccessOrFailure IMHO
l
@gildor whoops, you're right 🙂 , I didn't realize that when code inside
runCatching {}
fails, there is never a value returned. Probably the only option would be to call it like
runCatching(originalValue) {}
, but that's weird indeed. Ok, I think I will be good with the Pair/Map solution 😄.