 
   # Update items for the feed in parameter.
   def sync_feed(feed) do
-    parsed_feed = feed.url |> fetch_data |> parse_feed
-
+    with {:ok, data} <- fetch_data(feed.url),
+         {:ok, parsed_feed} <- parse_feed(data) do
+      update_feed(feed, parsed_feed)
+    else
+      {:error, code} ->
+        # Try to get a string representation of the error
+        code = case code do
+          str when is_bitstring(str) -> str
+          %{message: message} -> message
+          %{__struct__: code} -> to_string(code)
+          _ -> "Unknown error"
+        end
+
+        Logger.error "Error syncing " <> feed.url <> " : " <> code
+        feed |> Feed.changeset(%{sync_status: code}) |> Repo.update!
+    end
+  end
+
+  # TODO
+  def recalculate_sync_frequencies do
+    Feed
+    |> where(auto_frequency: true)
+    |> Repo.all
+    |> Enum.each(fn(feed) ->
+      latest =
+        Item
+        |> where(feed_id: ^feed.id)
+        |> order_by(desc: :date)
+        |> limit(5)
+        |> Repo.all
+    end)
+  end
+
+  # Update items for the feed in parameter using the parsed_feed.
+  defp update_feed(feed, parsed_feed) do
     items = Enum.map(parsed_feed.entries, fn(entry) ->
       %{
         feed_id: feed.id,


  alias Exagg.Feed
  alias Exagg.Item
  alias Exagg.Media
  alias Exagg.Repo

  import Ecto.Query

  end

  # Fetch data from the URL in parameter.
  defp fetch_data(url) do
    try do
      case HTTPotion.get(url, [follow_redirects: true, headers: ["User-Agent": "Exagg"]]) do
        %HTTPotion.Response{body: body} -> {:ok, body}
        %HTTPotion.ErrorResponse{message: message} -> {:error, message}
      end
    rescue
      ex -> {:error, ex}
    end
  end

  # Parse XML feed data.
  defp parse_feed(xml) do
    try do
       case FeederEx.parse(xml) do
          {:ok, feed, _} -> {:ok, feed}
          {:error, code} -> {:error, code}
       end
    rescue
      ex -> {:error, ex}
    catch
      ex -> {:error, ex}
    end
  end

