Skip to content

Commit

Permalink
Add an option to allow freeze to continue when a 404 error is returned
Browse files Browse the repository at this point in the history
	FREEZER_IGNORE_404_NOT_FOUND
  • Loading branch information
max-k committed Feb 12, 2014
1 parent 0f88d02 commit e795c18
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 3 deletions.
10 changes: 10 additions & 0 deletions docs/index.rst
Expand Up @@ -274,6 +274,16 @@ are accepted:

.. versionadded:: 0.12

``FREEZER_IGNORE_404_NOT_FOUND``
If set to ``True`` (defaults False), Frozen-Flask won't stop freezing when
404 error is returned by your application.
In this case, a warning will be printed on stdout and the static page will
be generated using your 404 error page handler or flask's default one.
This can be usefull during development phase if you have already referenced
pages wich aren't written yet.

.. versionadded:: 0.12

.. _mime-types:

Filenames and MIME types
Expand Down
15 changes: 13 additions & 2 deletions flask_frozen/__init__.py
Expand Up @@ -52,6 +52,8 @@ class MissingURLGeneratorWarning(Warning):
class MimetypeMismatchWarning(Warning):
pass

class NotFoundWarning(Warning):
pass

class Freezer(object):
"""
Expand Down Expand Up @@ -100,6 +102,7 @@ def init_app(self, app):
'application/octet-stream')
app.config.setdefault('FREEZER_IGNORE_MIMETYPE_WARNINGS', False)
app.config.setdefault('FREEZER_RELATIVE_URLS', False)
app.config.setdefault('FREEZER_IGNORE_404_NOT_FOUND', False)

def register_generator(self, function):
"""Register a function as an URL generator.
Expand Down Expand Up @@ -259,9 +262,17 @@ def _build_one(self, url):

# The client follows redirects by itself
# Any other status code is probably an error
# except we explictly want 404 errors to be skipped
# (eg. while application is in development)
ignore_404 = self.app.config['FREEZER_IGNORE_404_NOT_FOUND']
if response.status_code != 200:
raise ValueError('Unexpected status %r on URL %s' \
% (response.status, url))
if response.status_code == 404 and ignore_404:
warnings.warn('Ignored %r on URL %s' % (response.status, url),
NotFoundWarning,
stacklevel=3)
else:
raise ValueError('Unexpected status %r on URL %s' \
% (response.status, url))

destination_path = self.urlpath_to_filepath(url)
filename = os.path.join(self.root, *destination_path.split('/'))
Expand Down
34 changes: 33 additions & 1 deletion flask_frozen/tests.py
Expand Up @@ -21,7 +21,7 @@
from warnings import catch_warnings

from flask_frozen import (Freezer, walk_directory,
MissingURLGeneratorWarning, MimetypeMismatchWarning)
MissingURLGeneratorWarning, MimetypeMismatchWarning, NotFoundWarning)
from flask_frozen import test_app

try:
Expand Down Expand Up @@ -168,6 +168,15 @@ def make_app(self):
self.do_extra_config(app, freezer)
yield temp, app, freezer

@contextmanager
def make_app_with_404(self):
# Build an app with a link to a non-existent route
with self.make_app() as (temp, app, freezer):
@freezer.register_generator
def non_existent_url():
yield '/404/'
yield temp, app, freezer

@contextmanager
def built_app(self):
with self.make_app() as (temp, app, freezer):
Expand Down Expand Up @@ -271,6 +280,29 @@ def external_url():
else:
assert False, 'Expected ValueError'

def test_error_on_internal_404(self):
with self.make_app_with_404() as (temp, app, freezer):
# Test standard behaviour with 404 errors (freeze failure)
try:
freezer.freeze()
except ValueError as e:
error_msg = "Unexpected status '404 NOT FOUND' on URL /404/"
assert error_msg in e.args[0]
else:
assert False, 'Expected ValueError'

def test_warn_on_internal_404(self):
with self.make_app_with_404() as (temp, app, freezer):
# Enable 404 erros ignoring
app.config['FREEZER_IGNORE_404_NOT_FOUND'] = True
# Test warning with 404 errors when we choose to ignore them
with catch_warnings(record=True) as logged_warnings:
warnings.simplefilter("always")
freezer.freeze()
self.assertEqual(len(logged_warnings), 1)
self.assertEqual(logged_warnings[0].category,
NotFoundWarning)

def test_warn_on_missing_generator(self):
with self.make_app() as (temp, app, freezer):
# Add a new endpoint without URL generator
Expand Down

0 comments on commit e795c18

Please sign in to comment.