I opted to assume all failures are of the first type, which means my code should also behave as expected, but will be slower when encountering failures of the second time.
I'm actually curious, I think it would be easier to change my code to handle both types of errors, but I could be wrong since I don't know the scala stuff you are using that well.
The reason that the Scala code is so much shorter is because streams compose really well and a lot of common building blocks (such as the throttling) can be provided. This effect gets more important when the code base is growing.
Also, when things become more complicated, loops like the one you wrote tend to become very complicated. At least that has been my experience. It's fun to write it, but not so much to read or maintain it.
I think it’s better with functional languages like scala and clojure, because bad class hierarchies with inheritance are the worst abstractions, but Go hits the right balance for me and I think for large organizations that have a lot of devs who move on and off of code bases on a regular basis.
I agree that you can get a better result with powerful languages, but that it’s unlikely in large orgs. I think software engineering at scale is more about sociology than people admit or realize.