However, I'm not sure what you mean by "there are some cases where it makes sense to have multiple things that could failed grouped in the same function". I'm almost certainly misinterpreting what you're saying, but that sounds like setting up a situation where it's harder to know exactly what failed because you're grouping failure modes together, which now means you need to have more understanding/context of your application and the local execution environment surrounding the point of failure to reason about what actually happened.
Almost always, except cases where I can't usefully trap a somewhat questionable lower-level API, I only ever, ever program the "happy path" in Elixir and Erlang. If I find myself doing anything that even remotely looks like active defensive programming, then I catch myself, step back from my local problem, and realize I need to rethink the flow control of my application and probably either expand or deepen my supervision tree. I always tell people, "At this point Erlang feels less like a programming language to me and almost more like a mostly declarative DSL for creating distributed systems." :-)
That's truly one of the greatest things about OTP Supervisors in my opinion. When used diligently they really let you cleanly separate fault-tolerance concerns from your application code, and when doing code reviews they give you an immediately obvious place to start looking for leaky abstractions and tightly coupled subsystems.