diff --git a/aurweb/scripts/notify.py b/aurweb/scripts/notify.py index e49024d9..20e8a5d5 100755 --- a/aurweb/scripts/notify.py +++ b/aurweb/scripts/notify.py @@ -13,10 +13,12 @@ import aurweb.config import aurweb.db import aurweb.l10n -from aurweb import db +from aurweb import db, logging from aurweb.models import (PackageBase, PackageComaintainer, PackageComment, PackageNotification, PackageRequest, RequestType, TUVote, User) +logger = logging.get_logger(__name__) + aur_location = aurweb.config.get('options', 'aur_location') @@ -49,7 +51,7 @@ class Notification: body += '\n' + '[%d] %s' % (i + 1, ref) return body.rstrip() - def send(self): + def _send(self) -> None: sendmail = aurweb.config.get('notifications', 'sendmail') sender = aurweb.config.get('notifications', 'sender') reply_to = aurweb.config.get('notifications', 'reply-to') @@ -111,6 +113,14 @@ class Notification: server.sendmail(sender, deliver_to, msg.as_bytes()) server.quit() + def send(self) -> None: + try: + self._send() + except OSError as exc: + logger.error("Unable to emit notification due to an " + "OSError (precise exception following).") + logger.error(str(exc)) + class ResetKeyNotification(Notification): def __init__(self, uid): diff --git a/test/test_notify.py b/test/test_notify.py index dc6e7e3e..e0035976 100644 --- a/test/test_notify.py +++ b/test/test_notify.py @@ -1,4 +1,5 @@ from datetime import datetime +from logging import ERROR from typing import List from unittest import mock @@ -634,3 +635,32 @@ def test_notification_defaults(): assert notif.get_refs() == tuple() assert notif.get_headers() == dict() assert notif.get_cc() == list() + + +def test_notification_oserror(user: User, caplog: pytest.LogCaptureFixture): + """ Try sending a notification with a bad SMTP configuration. """ + caplog.set_level(ERROR) + config_get = config.get + + mocked_options = { + "sendmail": str(), + "smtp-server": "mail.server.xyz", + "smtp-port": "587", + "smtp-user": "notify@server.xyz", + "smtp-password": "notify_server_xyz", + "sender": "notify@server.xyz", + "reply-to": "no-reply@server.xyz" + } + + def mock_config_get(section: str, key: str) -> str: + if section == "notifications": + if key in mocked_options: + return mocked_options.get(key) + return config_get(section, key) + + notif = notify.WelcomeNotification(user.ID) + with mock.patch("aurweb.config.get", side_effect=mock_config_get): + notif.send() + + expected = "Unable to emit notification due to an OSError" + assert expected in caplog.text