diff --git a/src/wuttaweb/handler.py b/src/wuttaweb/handler.py index 615eae4..1fac0d7 100644 --- a/src/wuttaweb/handler.py +++ b/src/wuttaweb/handler.py @@ -2,7 +2,7 @@ ################################################################################ # # wuttaweb -- Web App for Wutta Framework -# Copyright © 2024 Lance Edgar +# Copyright © 2024-2025 Lance Edgar # # This file is part of Wutta Framework. # @@ -70,15 +70,7 @@ class WebHandler(GenericHandler): url = self.config.get("wuttaweb.favicon_url") if url: return url - - # nb. in rare circumstances i have received unhandled error email, - # which somehow was triggered by 'fanstatic.needed' being missing - # from the environ. not sure why that would happen, but it seems - # safe to ignore when it does - favicon is not *that* important. - if "fanstatic.needed" in request.environ: - return self.get_fanstatic_url(request, static.favicon) - - return "" + return self.get_fanstatic_url(request, static.favicon) def get_header_logo_url(self, request): """ diff --git a/src/wuttaweb/subscribers.py b/src/wuttaweb/subscribers.py index 5dba500..6fbd4b0 100644 --- a/src/wuttaweb/subscribers.py +++ b/src/wuttaweb/subscribers.py @@ -41,6 +41,7 @@ import logging from collections import OrderedDict from pyramid import threadlocal +from pyramid.httpexceptions import HTTPFound from wuttaweb import helpers from wuttaweb.db import Session @@ -123,6 +124,17 @@ def new_request(event): config = request.registry.settings["wutta_config"] app = config.get_app() + # nb. in rare circumstances i have received unhandled error email, + # which somehow was triggered by 'fanstatic.needed' being missing + # from the environ. not sure why that would happen, but it seems + # to when crawlers request a non-existent filename under the + # fanstatic path. there isn't a great way to handle it since + # e.g. can't show the normal error page if JS resources won't + # load, so we try a hail-mary redirect.. + # (nb. also we skip this if environ is empty, i.e. for tests) + if request.environ and "fanstatic.needed" not in request.environ: + raise HTTPFound(location=request.route_url("home")) + request.wutta_config = config def get_referrer(default=None): diff --git a/tests/test_handler.py b/tests/test_handler.py index b038e47..ad3cc7a 100644 --- a/tests/test_handler.py +++ b/tests/test_handler.py @@ -38,14 +38,6 @@ class TestWebHandler(WebTestCase): url = handler.get_fanstatic_url(self.request, static.logo) self.assertEqual(url, "/testing/fanstatic/wuttaweb_img/logo.png") - # error if environ missing config/data - environ = dict(self.request.environ) - del environ["fanstatic.needed"] - with patch.object(self.request, "environ", new=environ): - self.assertRaises( - KeyError, handler.get_fanstatic_url, self.request, static.logo - ) - def test_get_favicon_url(self): handler = self.make_handler() @@ -53,12 +45,6 @@ class TestWebHandler(WebTestCase): url = handler.get_favicon_url(self.request) self.assertEqual(url, "/fanstatic/wuttaweb_img/favicon.ico") - # returns empty if environ missing config/data - environ = dict(self.request.environ) - del environ["fanstatic.needed"] - with patch.object(self.request, "environ", new=environ): - self.assertEqual(handler.get_favicon_url(self.request), "") - # config override self.config.setdefault("wuttaweb.favicon_url", "/testing/other.ico") url = handler.get_favicon_url(self.request) diff --git a/tests/test_subscribers.py b/tests/test_subscribers.py index 501e160..da4e85a 100644 --- a/tests/test_subscribers.py +++ b/tests/test_subscribers.py @@ -7,6 +7,7 @@ from unittest.mock import MagicMock, patch from wuttjamaican.conf import WuttaConfig from pyramid import testing +from pyramid.httpexceptions import HTTPFound from pyramid.security import remember from wuttaweb import subscribers @@ -14,6 +15,10 @@ from wuttaweb import helpers from wuttaweb.auth import WuttaSecurityPolicy +# TODO: change import above +mod = subscribers + + class TestNewRequest(TestCase): def setUp(self): @@ -34,6 +39,14 @@ class TestNewRequest(TestCase): # request.registry.settings = {'wutta_config': self.config} return request + def test_missing_fanstatic_needed(self): + self.pyramid_config.add_route("home", "/") + event = MagicMock(request=self.request) + + # should redirect if 'fanstatic.needed' missing from environ + with patch.object(self.request, "environ", new={"foo": "bar"}): + self.assertRaises(HTTPFound, mod.new_request, event) + def test_wutta_config(self): event = MagicMock(request=self.request)