Rescue Me

When working with third party APIs you can sometime use rescue as another part of your toolset to control the flow of your code. In working with any API you usually send a request for data and process the response that is sent back by the server. Working extensive with the YouTube API recently I got to understand how I can use rescue as a normal part of my code. <!--more--> When requesting data from YouTube you either get the data you wanted or YouTube will send back one of an extensive list of errors. Luckily the YouTube API errors are relatively detailed and can get as specific as badRequest (400) when trying to access a Channel's data set or as unclear as forbidden (403).

I had to recently request a Channel's playlist and from there check whether each item on this playlist, which are videos, were private or removed by the user from their channel. Even though a video may have been permanently removed from YouTube, the playlist still retained the information associated with the video. So to definitively check whether a video has been removed I had to also attempt to request data with the asset information provided in the playlist data set. In trying to access information for a deleted video the YouTube API would respond with an error notFound (404). Knowing that this would be the error that would be raised I was able to structure my code so that it would catch this specific error through rescue and execute the the request to remove this item from the playlist data set. YouTube and more specifically the gem that I am using to communicate with the API, Yt gem, raised a very specific error that I was able to rescue.

playlist.playlist_items.each do |playlist_item|
    if playlist_item.private?
      playlist_item.delete
    end
  end

Initially my code fetched a YouTube channel's playlists iterated over each playlist item. Then checked whether those items had a privacy status of private. Which was simple because the Yt gem had a method for that. What I didn't account for was to check whether a video has been removed from YouTube. On YouTube, a playlistItem just contains reference data to the video. When you delete a video that has been added to a playlist, Youtube does a couple of cleanup tasks. First it changes the title on the playlistItem to 'Deleted Video'. Changes the privacy status to 'private'. This is why you will see "Deleted Video" or "Private Video" on playlists all across YouTube.

This forced me to delve deeper by checking the video asset itself using the information passed by playlistIems. When I started doing this, my method began to fail, in part because YouTube started sending back error responses which the Yt gem raised errors because the data that I was requesting was no longer available. In this specific case the error that was being raised is Yt::Errors::NoItems in response to the notFound (404) response sent by YouTube.

At first I was'nt sure how to approach this issue. Unfortunately Youtube doesn't provide a end point to check whether a video asset has been removed. I then figured out that if this error is the response I am consistently getting when I try to retrieve information on a removed video then I can rescue on this error and continue to safely remove the item referenced on the playlist. Arriving at this a conclusion I then modified my code to rescue on this specific error. Since I knew the specific error that was being raise I just set the rescue clause to that.

playlist.playlist_items.each do |playlist_item|
    begin
      if playlist_item.video.private?
        playlist_item.delete
      end
    rescue Yt::Errors::NoItems
      playlist_item.delete
    end
  end