How is this different from an app dying because of an unhandled exception in Java or Python?
It sounds like you're not using supervisors in a way they are supposed to be: the supervision tree is not for handling your application logic (I mean application in OTP sense). The supervision tree is there to ensure that there's always a way to bring your system to its initial, known-good, state. In a concurrent, but even more so in a distributed context, it's practically a given that you'll run into race conditions and other timing issues which result in loads of heisenbugs. Then, once that happens, you risk your app falling into an invalid state, in which it either ceases to function or continues working but gives wrong results. Erlang addresses this with pervasive immutability, generic servers (in OTP sense) and the supervision tree.
Immutability eliminates some common race conditions and makes sending messages in a distributed system have the same semantics as local message sends. Generic servers provide a well-defined interface for interacting with running processes no matter where they are, which allows for automated handling of initialization, finalization, error handling and upgrades in a concurrent-safe manner. And finally, supervision trees - as mentioned - define an orderly way of initializing, restaring, and terminating all the processes your application consists of and depends on. The supervision tree is not meant for error handling: its primary function is to bring the system to a known-good initial state. Notice that the supervision tree operations are synchronous, and the order of actions is deterministic and constant across runs, exactly because of this.
If you find your app dying because of "network hiccups" it just means that you don't handle them properly in your code. Supervision hierarchy is not meant - by default, although you could write your own supervisor - to handle application-level problems: that's your job, as an application author. If you have a Python client for some REST API, and you lose WiFi connection for a moment, requests will (by default, IIRC) throw an exception and if you don't handle it, your program will terminate. The difference with Erlang/OTP is that in Python, if at the moment of failure you had 10 threads which managed to fetch data before the connection broke and were currently munging it, they will also die immediately in a non-deterministic state. In Erlang, they would be shut down in a well-defined order.
TL;DR: supervisors are a low-level concept and should not be used for handling application logic. They are there to organize your processes and to provide a way to return the system to a known, deterministic state. Handling most of the error conditions still belongs to the app author, despite supervisors being there.