# Buggy code
def add_station(uri):
    """Fetches the URI content and extracts IRFiles"""

    irfs = []
    if isinstance(uri, unicode):
        uri = uri.encode("utf-8")

    if uri.lower().endswith(".pls") or uri.lower().endswith(".m3u"):
        try:
            sock = urlopen(uri)
        except EnvironmentError as e:
            encoding = util.get_locale_encoding()
            try:
                err = e.strerror.decode(encoding, "replace")
            except (TypeError, AttributeError):
                err = e.strerror[1].decode(encoding, "replace")
            qltk.ErrorMessage(None, _("Unable to add station"), err).run()
            return []

        if uri.lower().endswith(".pls"):
            irfs = ParsePLS(sock)
        elif uri.lower().endswith(".m3u"):
            irfs = ParseM3U(sock)

        sock.close()
    else:
        try:
            irfs = [IRFile(uri)]
        except ValueError as err:
            qltk.ErrorMessage(None, _("Unable to add station"), err).run()

    return irfs


# Traceback (TypeError)
=== SYSTEM INFORMATION:
Quod Libet 3.6.2
Mutagen 1.31
Python 2.7.11+ (default, Apr 17 2016, 14:00:29)
[GCC 5.3.1 20160413] linux2
Platform Linux-4.4.0-24-generic-x86_64-with-Ubuntu-16.04-xenial

=== STACK TRACE
Traceback (most recent call last):

File "/usr/lib/python2.7/dist-packages/quodlibet/browsers/iradio.py", line 803, in __add
self.__add_station(uri)

File "/usr/lib/python2.7/dist-packages/quodlibet/browsers/iradio.py", line 806, in __add_station
irfs = add_station(uri)

File "/usr/lib/python2.7/dist-packages/quodlibet/browsers/iradio.py", line 213, in add_station
err = e.strerror[1].decode(encoding, 'replace')

TypeError: 'NoneType' object has no attribute '__getitem__'


=== LOG:
D: 991.28: PlaylistMux.go_to: Told to go to <Gtk.TreeIter object at 0x7f1efc8bd258 (GtkTreeIter at 0x7f1f200bd0e0)>
D: 991.28: QueueModel.go_to: Told to go to None
D: 991.28: PlaylistModel.go_to: Told to go to <Gtk.TreeIter object at 0x7f1efc8bd258 (GtkTreeIter at 0x7f1f200bd0e0)>
D: 991.28: GStreamerPlayer._end: End song
D: 991.28: util.cover.manager.failure: Didn't get cover from FilesystemCover: This source is incapable of fetching covers
D: 991.29: util.cover.manager.failure: Didn't get cover from EmbedCover: This source is incapable of fetching covers
D: 991.29: util.cover.manager.failure: Didn't get cover from MusicBrainzCover: MBID is required to fetch the cover
D: 991.29: GStreamerPlayer._end: Next song
D: 991.39: SongLibrary._changed: Changing 2 items.
D: 991.39: qltk.completion.__update_song: Updating tag model for 2 songs
D: 991.39: qltk.completion.__update_song: Done updating tag model for 2 songs
D: 992.07: player.gstbe.player.__message: Recalculate latency
D: 992.07: SongLibrary._changed: Changing 1 items.
D: 992.07: qltk.completion.__update_song: Updating tag model for 1 songs
D: 992.07: qltk.completion.__update_song: Done updating tag model for 1 songs
D: 996.70: util.cover.manager.failure: Didn't get cover from FilesystemCover: This source is incapable of fetching covers
D: 996.70: util.cover.manager.failure: Didn't get cover from EmbedCover: This source is incapable of fetching covers
D: 996.70: util.cover.manager.failure: Didn't get cover from MusicBrainzCover: MBID is required to fetch the cover
D: 996.71: SongLibrary._changed: Changing 1 items.
D: 996.71: qltk.completion.__update_song: Updating tag model for 1 songs
D: 996.71: qltk.completion.__update_song: Done updating tag model for 1 songs
D: 039.71: util.cover.manager.failure: Didn't get cover from FilesystemCover: This source is incapable of fetching covers
D: 039.71: util.cover.manager.failure: Didn't get cover from EmbedCover: This source is incapable of fetching covers
D: 039.71: util.cover.manager.failure: Didn't get cover from MusicBrainzCover: MBID is required to fetch the cover
D: 039.80: SongLibrary._changed: Changing 2 items.
D: 039.80: qltk.completion.__update_song: Updating tag model for 2 songs
D: 039.80: qltk.completion.__update_song: Done updating tag model for 2 songs
D: 171.42: GStreamerPlayer.go_to: Going to <Gtk.TreeIter object at 0x7f1efc8bd460 (GtkTreeIter at 0x7f1f6400a560)>
D: 171.42: PlaylistMux.go_to: Told to go to <Gtk.TreeIter object at 0x7f1efc8bd460 (GtkTreeIter at 0x7f1f6400a560)>
D: 171.42: QueueModel.go_to: Told to go to None
D: 171.42: PlaylistModel.go_to: Told to go to <Gtk.TreeIter object at 0x7f1efc8bd460 (GtkTreeIter at 0x7f1f6400a560)>
D: 171.43: GStreamerPlayer._end: End song
D: 171.43: util.cover.manager.failure: Didn't get cover from FilesystemCover: This source is incapable of fetching covers
D: 171.43: util.cover.manager.failure: Didn't get cover from EmbedCover: This source is incapable of fetching covers
D: 171.43: util.cover.manager.failure: Didn't get cover from MusicBrainzCover: MBID is required to fetch the cover
D: 171.43: GStreamerPlayer._end: Next song
W: Could not resolve server name
W: Error resolving 'pub3.di.fm': Name or service not known (2), URL: http://pub3.di.fm:80/di_chillstep_aac, Redirect to: (NULL)
D: 171.74: SongLibrary._changed: Changing 2 items.
D: 171.74: qltk.completion.__update_song: Updating tag model for 2 songs
D: 171.74: qltk.completion.__update_song: Done updating tag model for 2 songs
D: 175.50: GStreamerPlayer.go_to: Going to <Gtk.TreeIter object at 0x7f1efc8d9ef0 (GtkTreeIter at 0x7f1f2001df20)>
D: 175.50: PlaylistMux.go_to: Told to go to <Gtk.TreeIter object at 0x7f1efc8d9ef0 (GtkTreeIter at 0x7f1f2001df20)>
D: 175.50: QueueModel.go_to: Told to go to None
D: 175.50: PlaylistModel.go_to: Told to go to <Gtk.TreeIter object at 0x7f1efc8d9ef0 (GtkTreeIter at 0x7f1f2001df20)>
D: 175.50: GStreamerPlayer._end: End song
D: 175.50: util.cover.manager.failure: Didn't get cover from FilesystemCover: This source is incapable of fetching covers
D: 175.50: util.cover.manager.failure: Didn't get cover from EmbedCover: This source is incapable of fetching covers
D: 175.50: util.cover.manager.failure: Didn't get cover from MusicBrainzCover: MBID is required to fetch the cover
D: 175.51: GStreamerPlayer._end: Next song
D: 175.55: SongLibrary._changed: Changing 1 items.
D: 175.56: qltk.completion.__update_song: Updating tag model for 1 songs
D: 175.56: qltk.completion.__update_song: Done updating tag model for 1 songs
D: 185.59: GStreamerPlayer.go_to: Going to <Gtk.TreeIter object at 0x7f1efc8bd460 (GtkTreeIter at 0x7f1ee800d8c0)>
D: 185.59: PlaylistMux.go_to: Told to go to <Gtk.TreeIter object at 0x7f1efc8bd460 (GtkTreeIter at 0x7f1ee800d8c0)>
D: 185.59: QueueModel.go_to: Told to go to None
D: 185.59: PlaylistModel.go_to: Told to go to <Gtk.TreeIter object at 0x7f1efc8bd460 (GtkTreeIter at 0x7f1ee800d8c0)>
D: 185.59: GStreamerPlayer._end: End song
D: 185.59: util.cover.manager.failure: Didn't get cover from FilesystemCover: This source is incapable of fetching covers
D: 185.59: util.cover.manager.failure: Didn't get cover from EmbedCover: This source is incapable of fetching covers
D: 185.59: util.cover.manager.failure: Didn't get cover from MusicBrainzCover: MBID is required to fetch the cover
D: 185.60: GStreamerPlayer._end: Next song
D: 185.66: SongLibrary._changed: Changing 1 items.
D: 185.67: qltk.completion.__update_song: Updating tag model for 1 songs
D: 185.67: qltk.completion.__update_song: Done updating tag model for 1 songs
D: 204.15: config.save: Writing config...
D: 204.16: library.save: Saving all libraries...
D: 204.16: SongLibrary.save: Saving contents to '/home/CreamyCookie/.quodlibet/stations_all'.
D: 204.57: SongLibrary.save: Saving contents to '/home/CreamyCookie/.quodlibet/stations'.
W: A network error occurred, or the server closed the connection unexpectedly
W: Could not connect: Socket I/O timed out (7), URL: http://72.13.91.147, Redirect to: (NULL)
D: 278.08: PlaylistModel.set: Clearing model.
D: 278.08: PlaylistModel.set: Setting 48 songs.
D: 278.08: PlaylistModel.set: Done filling model.
D: 278.15: PlaylistModel.set: Clearing model.
D: 278.15: PlaylistModel.set: Setting 48 songs.
D: 278.15: PlaylistModel.set: Done filling model.

# Fixed code
def add_station(uri):
    """Fetches the URI content and extracts IRFiles
    Returns None in error, else a possibly filled list of stations"""

    irfs = []
    if isinstance(uri, unicode):
        uri = uri.encode("utf-8")

    if uri.lower().endswith(".pls") or uri.lower().endswith(".m3u"):
        try:
            sock = urlopen(uri)
        except EnvironmentError as e:
            print_d("Got %s from %s" % (uri, e))
            encoding = util.get_locale_encoding()
            try:
                err = e.strerror.decode(encoding, "replace")
            except TypeError:
                err = e.strerror[1].decode(encoding, "replace")
            except AttributeError:
                # Give up and display the exception - may be useful HTTP info
                err = str(e)
            ErrorMessage(None, _("Unable to add station"), escape(err)).run()
            return None

        if uri.lower().endswith(".pls"):
            irfs = ParsePLS(sock)
        elif uri.lower().endswith(".m3u"):
            irfs = ParseM3U(sock)

        sock.close()
    else:
        try:
            irfs = [IRFile(uri)]
        except ValueError as err:
            ErrorMessage(None, _("Unable to add station"), err).run()

    return irfs