diff --git a/discord_rss_bot/feeds.py b/discord_rss_bot/feeds.py
index 6f464d6..d91557a 100644
--- a/discord_rss_bot/feeds.py
+++ b/discord_rss_bot/feeds.py
@@ -1,4 +1,7 @@
 from discord_webhook import DiscordWebhook
+from pydantic import BaseModel
+from reader import FeedExistsError, FeedNotFoundError, InvalidFeedURLError, ParseError, StorageError
+from requests import Response
 
 from discord_rss_bot.settings import logger, reader
 
@@ -7,28 +10,118 @@ def check_feeds() -> None:
     """Check all feeds"""
     reader.update_feeds()
     entries = reader.get_entries(read=False)
-    _check_feed(entries)
+    send_to_discord(entries)
 
 
 def check_feed(feed_url: str) -> None:
     """Check a single feed"""
     reader.update_feeds()
     entry = reader.get_entries(feed=feed_url, read=False)
-    _check_feed(entry)
+    send_to_discord(entry)
 
 
-def _check_feed(entries) -> None:
-    for entry in entries:
-        reader.mark_entry_as_read(entry)
-        logger.debug(f"New entry: {entry.title}")
+class NoWebhookFoundError(Exception):
+    """No webhook found error."""
 
-        webhook_url = reader.get_tag(entry.feed.url, "webhook")
-        if webhook_url:
-            logger.debug(f"Sending to webhook: {webhook_url}")
-            webhook = DiscordWebhook(url=str(webhook_url), content=f":robot: :mega: New entry: {entry.title}\n"
-                                                                   f"{entry.link}", rate_limit_retry=True)
-            response = webhook.execute()
-            if not response.ok:
-                # TODO: Send error to discord
-                logger.error(f"Error: {response.status_code} {response.reason}")
-                reader.mark_entry_as_unread(entry)
+    def __init__(self, message):
+        self.message = message
+
+    def __str__(self):
+        return self.message
+
+
+def send_to_discord(entry) -> Response:
+    """
+    Send entries to Discord.
+
+    Args:
+        entry: The entry to send.
+
+    Returns:
+        Response: The response from the webhook.
+    """
+
+    reader.mark_entry_as_read(entry)
+    logger.debug(f"New entry: {entry.title}")
+
+    webhook_url = reader.get_tag(entry.feed.url, "webhook")
+    if not webhook_url:
+        logger.error(f"No webhook found for feed: {entry.feed.url}")
+        raise NoWebhookFoundError(f"No webhook found for feed: {entry.feed.url}")
+
+    logger.debug(f"Sending to webhook: {webhook_url}")
+    webhook = DiscordWebhook(url=str(webhook_url), content=f":robot: :mega: New entry: {entry.title}\n"
+                                                           f"{entry.link}", rate_limit_retry=True)
+    response = webhook.execute()
+    if not response.ok:
+        # TODO: Send error to discord
+        logger.error(f"Error: {response.status_code} {response.reason}")
+        reader.mark_entry_as_unread(entry)
+    return response
+
+
+class IfFeedError(BaseModel):
+    """Update a feed."""
+    feed_url: str
+    webhook: str
+    error: bool
+    err_msg: str = ""
+    exception: str = ""
+
+
+def update_feed(feed_url: str, webhook: str) -> IfFeedError:
+    """
+    Update a feed.
+
+    Args:
+        feed_url: The feed to update.
+        webhook: The webhook to use.
+
+    Returns:
+        IfFeedError: Error or not.
+    """
+    try:
+        reader.update_feed(feed_url)
+
+    except FeedNotFoundError as error:
+        error_msg = "Feed not found"
+        logger.error(error_msg, exc_info=True)
+        return IfFeedError(error=True, err_msg=error_msg, feed_url=feed_url, webhook=webhook, exception=error.message)
+
+    except ParseError as error:
+        error_msg = "An error occurred while getting/parsing feed"
+        logger.error(error_msg, exc_info=True)
+        return IfFeedError(error=True, err_msg=error_msg, feed_url=feed_url, webhook=webhook, exception=error.message)
+
+    except StorageError as error:
+        error_msg = "An exception was raised by the underlying storage"
+        logger.error(error_msg, exc_info=True)
+        return IfFeedError(error=True, err_msg=error_msg, feed_url=feed_url, webhook=webhook, exception=error.message)
+
+    return IfFeedError(error=False, feed_url=feed_url, webhook=webhook)
+
+
+def add_feed(feed_url: str, webhook: str, exist_ok=False, allow_invalid_url=False) -> IfFeedError:
+    """
+    Add a feed.
+
+    Args:
+        feed_url: The feed to add.
+        webhook:  The webhook to use.
+        exist_ok:  If the feed already exists, do nothing.
+        allow_invalid_url:  If the feed url is invalid, add it anyway.
+
+    Returns:
+        IfFeedError: Error or not.
+    """
+    try:
+        reader.add_feed(feed=feed_url, exist_ok=exist_ok, allow_invalid_url=allow_invalid_url)
+    except FeedExistsError as error:
+        error_msg = "Feed already exists"
+        logger.error(f"{error_msg}: {error}")
+        return IfFeedError(error=True, err_msg=error_msg, feed_url=feed_url, webhook=webhook, exception=error.message)
+
+    except InvalidFeedURLError as error:
+        error_msg = "Invalid feed URL"
+        logger.error(f"{error_msg}: {error}")
+        return IfFeedError(error=True, err_msg=error_msg, feed_url=feed_url, webhook=webhook, exception=error.message)
diff --git a/discord_rss_bot/main.py b/discord_rss_bot/main.py
index 888e067..71b750d 100644
--- a/discord_rss_bot/main.py
+++ b/discord_rss_bot/main.py
@@ -4,13 +4,14 @@ from functools import cache
 
 import uvicorn
 from apscheduler.schedulers.background import BackgroundScheduler
-from fastapi import FastAPI, Form, Request
+from fastapi import FastAPI, Form, HTTPException, Request
 from fastapi.responses import FileResponse, HTMLResponse
 from fastapi.templating import Jinja2Templates
-from reader import FeedExistsError
+from reader import ResourceNotFoundError
 
-from discord_rss_bot.feeds import _check_feed
+from discord_rss_bot.feeds import add_feed, send_to_discord, update_feed
 from discord_rss_bot.settings import logger, read_settings_file, reader
+from discord_rss_bot.webhooks import set_hook_by_name
 
 app = FastAPI()
 templates = Jinja2Templates(directory="templates")
@@ -28,7 +29,7 @@ def check_feed(request: Request, feed_url: str = Form()):
     """Check all feeds"""
     reader.update_feeds()
     entry = reader.get_entries(feed=feed_url, read=False)
-    _check_feed(entry)
+    send_to_discord(entry)
 
     logger.info(f"Get feed: {feed_url}")
     feed = reader.get_feed(feed_url)
@@ -149,13 +150,6 @@ def create_list_of_webhooks():
     return enum.Enum("DiscordWebhooks", list_of_webhooks)
 
 
-def get_hook_by_name(name):
-    """Get a webhook by name."""
-    settings = read_settings_file()
-    logger.debug(f"Webhook name: {name} with URL: {settings['webhooks'][name]}")
-    return settings["webhooks"][name]
-
-
 @app.post("/add")
 async def create_feed(feed_url: str = Form(), webhook_dropdown: str = Form()):
     """
@@ -170,18 +164,25 @@ async def create_feed(feed_url: str = Form(), webhook_dropdown: str = Form()):
     """
     logger.info(f"Add feed: {feed_url}")
     logger.info(f"Webhook: {webhook_dropdown}")
-    try:
-        reader.add_feed(feed_url)
-    except FeedExistsError as error:
-        logger.error(f"Feed already exists: {error}")
-        return {"error": "Feed already exists."}
-    reader.update_feed(feed_url)
-    webhook_url = get_hook_by_name(webhook_dropdown)
-    reader.set_tag(feed_url, "webhook", webhook_url)
+
+    # Update a single feed. The feed will be updated even if updates are disabled for it.
+    updated_feed = update_feed(feed_url, webhook_dropdown)
+
+    # Add a new feed to the database.
+    added_feed = add_feed(feed_url, webhook_dropdown)
+
+    if updated_feed.error or added_feed.error:
+        error_dict = {"error": updated_feed.error, "feed": updated_feed.feed_url, "webhook": updated_feed.webhook,
+                      "exception": updated_feed.exception}
+        return HTTPException(status_code=500, detail=error_dict)
+
+    # Check if set_hook_by_name() was successful.
+    if isinstance(set_hook_by_name(name=webhook_dropdown, feed_url=feed_url), ResourceNotFoundError):
+        return set_hook_by_name(name=webhook_dropdown, feed_url=feed_url)
 
     new_tag = reader.get_tag(feed_url, "webhook")
     logger.info(f"New tag: {new_tag}")
-    return {"feed_url": str(feed_url), "status": "added", "webhook": webhook_url}
+    return {"feed_url": str(feed_url), "status": "added"}
 
 
 @app.get("/add", response_class=HTMLResponse)
diff --git a/discord_rss_bot/webhooks.py b/discord_rss_bot/webhooks.py
new file mode 100644
index 0000000..6ece80c
--- /dev/null
+++ b/discord_rss_bot/webhooks.py
@@ -0,0 +1,24 @@
+from fastapi import HTTPException
+from reader import ResourceNotFoundError
+
+from discord_rss_bot.settings import logger, read_settings_file, reader
+
+
+def set_hook_by_name(name: str, feed_url: str) -> None or HTTPException:
+    """Set a webhook by name.
+
+    Args:
+        name: The name of the webhook.
+        feed_url: The feed to set the webhook for.
+
+    Returns:
+        HTTPException: The HTTP exception if the webhook was not found, otherwise None.
+    """
+    settings = read_settings_file()
+    logger.debug(f"Webhook name: {name} with URL: {settings['webhooks'][name]}")
+    webhook_url = settings["webhooks"][name]
+    try:
+        reader.set_tag(feed_url, "webhook", webhook_url)
+    except ResourceNotFoundError as e:
+        logger.error(f"ResourceNotFoundError: {e}")
+        return HTTPException(status_code=500, detail=f"ResourceNotFoundError: Could not set webhook: {e}")