﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
35669	Improve `RuntimeError: Max post-process passes exceeded.` error	Michael	Jae Hyuck Sa 	"Having just spend 3 hours trying to debug a collect static issue, to help future travellers, I recommend printing the files that caused max depth to be exceeded, often when a file references itself it causes recursion, but the only clue it currently prints is 'All' which does not narrow down the problem. We can surely do better than that! The proposed change prints the problem files only that keep chaning and can't be resolved:

So instead of getting:
{{{
Post-processing 'All' failed!
}}}
We get the new and improved:
{{{
Post-processing 'jsapp/jsapp/notify.min.js' failed!
}}}
Or if more than one file:
{{{
Post-processing 'jsapp/jsapp/notify.min.js, jsapp/jsapp/somethingelse.min.js' failed!
}}}

I recommend changing from:
{{{
# contrib/staticfiles/storage.py line 313: in def post_process(self, paths, dry_run=False, **options):
        unresolved_paths = []
        for i in range(self.max_post_process_passes):
            substitutions = False
            for name, hashed_name, processed, subst in self._post_process(
                paths, adjustable_paths, hashed_files
            ):
                # Overwrite since hashed_name may be newer.
                processed_adjustable_paths[name] = (name, hashed_name, processed)
                if subst and i == self.max_post_process_passes - 1:
                    unresolved_paths.append(name)
                substitutions = substitutions or subst

            if not substitutions:
                break

        if substitutions:
            problem_paths_str = "", "".join(unresolved_paths) if unresolved_paths else ""All""
            yield problem_paths_str, None, RuntimeError(""Max post-process passes exceeded."")
}}}

I recommend changing to (see the comments on the right of the proposed changed lines 1/5 to 5/5):
{{{
# contrib/staticfiles/storage.py line 313: in def post_process(self, paths, dry_run=False, **options):
        unresolved_paths = []                                            # < -- add this line 1/5
        for i in range(self.max_post_process_passes):
            substitutions = False
            for name, hashed_name, processed, subst in self._post_process(
                paths, adjustable_paths, hashed_files
            ):
                # Overwrite since hashed_name may be newer.
                processed_adjustable_paths[name] = (name, hashed_name, processed)
                if subst and i == self.max_post_process_passes - 1:      # < -- add this line 2/5
                    unresolved_paths.append(name)                        # < -- add this line 3/5
                substitutions = substitutions or subst

            if not substitutions:
                break

        if substitutions:
            problem_paths_str = "", "".join(unresolved_paths) if unresolved_paths else ""All""     # < -- add this line 4/5
            yield problem_paths_str, None, RuntimeError(""Max post-process passes exceeded."")   # < -- change this line 5/5
}}}
"	Cleanup/optimization	closed	contrib.staticfiles	5.1	Normal	fixed	collect static errors	Michael	Ready for checkin	1	0	0	0	1	0
