I\'m trying to get better at handling exceptions but I feel like my code gets very ugly, unreadable and cluttered when I try my best to catch them. I would love to see how other
First, read my article on exception handling:
http://ericlippert.com/2008/09/10/vexing-exceptions/
My advice is: you must handle the "vexing exceptions" and "exogenous exceptions" that can be thrown by your code. Vexing exceptions are "non exceptional" exceptions and so you have to handle them. Exogenous exceptions can happen due to considerations beyond your control, and so you have to handle them.
You must not handle the fatal and boneheaded exceptions. The boneheaded exceptions you don't need to handle because you are never going to do anything that causes them to be thrown. If they are thrown then you have a bug and the solution is fix the bug. Don't handle the exception; that's hiding the bug. And you can't meaningfully handle fatal exceptions because they're fatal. The process is about to go down. You might consider logging the fatal exception, but keep in mind that the logging subsystem might be the thing that triggered the fatal exception in the first place.
In short: handle only those exceptions that can possibly happen that you know how to handle. If you don't know how to handle it, leave it to your caller; the caller might know better than you do.
In your particular case: don't handle any exceptions in this method. Let the caller deal with the exceptions. If the caller passes you an url that cannot be resolved, crash them. If the bad url is a bug then the caller has a bug to fix and you are doing them a favour by bringing it to their attention. If the bad url is not a bug -- say, because the user's internet connection is messed up -- then the caller needs to find out why the fetch failed by interrogating the real exception. The caller might know how to recover, so help them.