From 90fe9141ded9f7005546e9a66f31fd196f60e7e4 Mon Sep 17 00:00:00 2001 From: Aymeric Augustin Date: Sun, 28 Apr 2013 16:45:05 +0200 Subject: [PATCH] Fixed #18986 -- Improved error message for missing files in CachedStaticFilesStorage. Thanks zyegfryed for his work on the patch. --- .../management/commands/collectstatic.py | 6 ++++++ django/contrib/staticfiles/storage.py | 5 ++++- .../staticfiles_tests/project/faulty/faulty.css | 1 + tests/staticfiles_tests/tests.py | 17 ++++++++++++++++- 4 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 tests/staticfiles_tests/project/faulty/faulty.css diff --git a/django/contrib/staticfiles/management/commands/collectstatic.py b/django/contrib/staticfiles/management/commands/collectstatic.py index 6116f31efc..22fdac7c76 100644 --- a/django/contrib/staticfiles/management/commands/collectstatic.py +++ b/django/contrib/staticfiles/management/commands/collectstatic.py @@ -116,6 +116,12 @@ class Command(NoArgsCommand): processor = self.storage.post_process(found_files, dry_run=self.dry_run) for original_path, processed_path, processed in processor: + if isinstance(processed, Exception): + self.stderr.write("Post-processing '%s' failed!" % original_path) + # Add a blank line before the traceback, otherwise it's + # too easy to miss the relevant part of the error message. + self.stderr.write("") + raise processed if processed: self.log("Post-processed '%s' as '%s'" % (original_path, processed_path), level=1) diff --git a/django/contrib/staticfiles/storage.py b/django/contrib/staticfiles/storage.py index f444e12c19..d085cf723f 100644 --- a/django/contrib/staticfiles/storage.py +++ b/django/contrib/staticfiles/storage.py @@ -251,7 +251,10 @@ class CachedFilesMixin(object): for patterns in self._patterns.values(): for pattern, template in patterns: converter = self.url_converter(name, template) - content = pattern.sub(converter, content) + try: + content = pattern.sub(converter, content) + except ValueError as exc: + yield name, None, exc if hashed_file_exists: self.delete(hashed_name) # then save the processed result diff --git a/tests/staticfiles_tests/project/faulty/faulty.css b/tests/staticfiles_tests/project/faulty/faulty.css new file mode 100644 index 0000000000..ca57c77e55 --- /dev/null +++ b/tests/staticfiles_tests/project/faulty/faulty.css @@ -0,0 +1 @@ +@import url("missing.css"); diff --git a/tests/staticfiles_tests/tests.py b/tests/staticfiles_tests/tests.py index 0391b8b018..912dcffe83 100644 --- a/tests/staticfiles_tests/tests.py +++ b/tests/staticfiles_tests/tests.py @@ -244,7 +244,7 @@ class TestCollection(CollectionTestCase, TestDefaults): class TestCollectionClear(CollectionTestCase): """ - Test the ``--clear`` option of the ``collectstatic`` managemenet command. + Test the ``--clear`` option of the ``collectstatic`` management command. """ def run_collectstatic(self, **kwargs): clear_filepath = os.path.join(settings.STATIC_ROOT, 'cleared.txt') @@ -550,6 +550,21 @@ class TestCollectionCachedStorage(BaseCollectionTestCase, self.assertNotIn(b"cached/other.css", content) self.assertIn(b"other.d41d8cd98f00.css", content) + @override_settings( + STATICFILES_DIRS=(os.path.join(TEST_ROOT, 'project', 'faulty'),), + STATICFILES_FINDERS=('django.contrib.staticfiles.finders.FileSystemFinder',), + ) + def test_post_processing_failure(self): + """ + Test that post_processing indicates the origin of the error when it + fails. Regression test for #18986. + """ + finders._finders.clear() + err = six.StringIO() + with self.assertRaises(Exception) as cm: + call_command('collectstatic', interactive=False, verbosity=0, stderr=err) + self.assertEqual("Post-processing 'faulty.css' failed!\n\n", err.getvalue()) + # we set DEBUG to False here since the template tag wouldn't work otherwise @override_settings(**dict(TEST_SETTINGS,