# Buggy code
def find_blocks(self, allowed_blocks=None, collect_raw_data=True):
    """Find all top-level blocks in the data."""
    if allowed_blocks is None:
        allowed_blocks = {"snapshot", "macro", "materialization", "docs"}

    for tag in self.tag_parser.find_tags():
        if tag.block_type_name in _CONTROL_FLOW_TAGS:
            self.stack.append(tag.block_type_name)
        elif tag.block_type_name in _CONTROL_FLOW_END_TAGS:
            found = None
            if self.stack:
                found = self.stack.pop()
            else:
                expected = _CONTROL_FLOW_END_TAGS[tag.block_type_name]
                dbt.exceptions.raise_compiler_error(
                    (
                        "Got an unexpected control flow end tag, got {} but "
                        "never saw a preceeding {} (@ {})"
                    ).format(tag.block_type_name, expected, tag.start)
                )
            expected = _CONTROL_FLOW_TAGS[found]
            if expected != tag.block_type_name:
                dbt.exceptions.raise_compiler_error(
                    (
                        "Got an unexpected control flow end tag, got {} but "
                        "expected {} next (@ {})"
                    ).format(tag.block_type_name, expected, tag.start)
                )

        if tag.block_type_name in allowed_blocks:
            if self.stack:
                dbt.exceptions.raise_compiler_error(
                    (
                        "Got a block definition inside control flow at {}. "
                        "All dbt block definitions must be at the top level"
                    ).format(tag.start)
                )
            if self.current is not None:
                dbt.exceptions.raise_compiler_error(
                    duplicate_tags.format(outer=self.current, inner=tag)
                )
            if collect_raw_data:
                raw_data = self.data[self.last_position : tag.start]
                self.last_position = tag.start
                if raw_data:
                    yield BlockData(raw_data)
            self.current = tag

        elif self.is_current_end(tag):
            self.last_position = tag.end
            yield BlockTag(
                block_type_name=self.current.block_type_name,
                block_name=self.current.block_name,
                contents=self.data[self.current.end : tag.start],
                full_block=self.data[self.current.start : tag.end],
            )
            self.current = None

    if self.current:
        dbt.exceptions.raise_compiler_error(
            (
                "Reached EOF without finding a close block for "
                "{0.block_type_name} (from {0.end})"
            ).format(self.current)
        )

    if collect_raw_data:
        raw_data = self.data[self.last_position :]
        if raw_data:
            yield BlockData(raw_data)


# Traceback (AttributeError)
Running with dbt=0.15.2-a1
Encountered an error:
Traceback (most recent call last):
File "/Users/drew/fishtown/dbt/core/dbt/main.py", line 80, in main
results, succeeded = handle_and_check(args)
File "/Users/drew/fishtown/dbt/core/dbt/main.py", line 158, in handle_and_check
task, res = run_from_args(parsed)
File "/Users/drew/fishtown/dbt/core/dbt/main.py", line 210, in run_from_args
results = task.run()
File "/Users/drew/fishtown/dbt/core/dbt/task/runnable.py", line 300, in run
self._runtime_initialize()
File "/Users/drew/fishtown/dbt/core/dbt/task/runnable.py", line 81, in _runtime_initialize
super()._runtime_initialize()
File "/Users/drew/fishtown/dbt/core/dbt/task/runnable.py", line 54, in _runtime_initialize
self.load_manifest()
File "/Users/drew/fishtown/dbt/core/dbt/task/runnable.py", line 46, in load_manifest
self.manifest = get_full_manifest(self.config)
File "/Users/drew/fishtown/dbt/core/dbt/perf_utils.py", line 23, in get_full_manifest
return load_manifest(config, internal, set_header)
File "/Users/drew/fishtown/dbt/core/dbt/parser/manifest.py", line 441, in load_manifest
return ManifestLoader.load_all(config, internal_manifest, macro_hook)
File "/Users/drew/fishtown/dbt/core/dbt/parser/manifest.py", line 329, in load_all
loader.load(internal_manifest=internal_manifest)
File "/Users/drew/fishtown/dbt/core/dbt/parser/manifest.py", line 200, in load
self.parse_project(project, macro_manifest, old_results)
File "/Users/drew/fishtown/dbt/core/dbt/parser/manifest.py", line 174, in parse_project
self.parse_with_cache(path, parser, old_results)
File "/Users/drew/fishtown/dbt/core/dbt/parser/manifest.py", line 133, in parse_with_cache
parser.parse_file(block)
File "/Users/drew/fishtown/dbt/core/dbt/parser/docs.py", line 90, in parse_file
for block in searcher:
File "/Users/drew/fishtown/dbt/core/dbt/parser/search.py", line 125, in __iter__
for block in self.extract_blocks(entry):
File "/Users/drew/fishtown/dbt/core/dbt/parser/search.py", line 110, in extract_blocks
collect_raw_data=False
File "/Users/drew/fishtown/dbt/core/dbt/clients/jinja.py", line 399, in extract_toplevel_blocks
collect_raw_data=collect_raw_data
File "/Users/drew/fishtown/dbt/core/dbt/clients/_jinja_blocks.py", line 371, in lex_for_blocks
collect_raw_data=collect_raw_data))
File "/Users/drew/fishtown/dbt/core/dbt/clients/_jinja_blocks.py", line 362, in find_blocks
).format(self.current))
File "/Users/drew/fishtown/dbt/core/dbt/exceptions.py", line 357, in raise_compiler_error
raise CompilationException(msg, node)
dbt.exceptions.CompilationException: <exception str() failed>

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/Users/drew/fishtown/dbt/env/bin/dbt", line 7, in <module>
exec(compile(f.read(), __file__, 'exec'))
File "/Users/drew/fishtown/dbt/core/scripts/dbt", line 7, in <module>
dbt.main.main(sys.argv[1:])
File "/Users/drew/fishtown/dbt/core/dbt/main.py", line 96, in main
logger.warning(str(e))
File "/Users/drew/fishtown/dbt/core/dbt/exceptions.py", line 99, in __str__
node_string = " in {}".format(self.node_to_string(self.node))
File "/Users/drew/fishtown/dbt/core/dbt/exceptions.py", line 66, in node_to_string
node.resource_type,
AttributeError: 'NotImplementedType' object has no attribute 'resource_type'

# Fixed code
def find_blocks(self, allowed_blocks=None, collect_raw_data=True):
    """Find all top-level blocks in the data."""
    if allowed_blocks is None:
        allowed_blocks = {"snapshot", "macro", "materialization", "docs"}

    for tag in self.tag_parser.find_tags():
        if tag.block_type_name in _CONTROL_FLOW_TAGS:
            self.stack.append(tag.block_type_name)
        elif tag.block_type_name in _CONTROL_FLOW_END_TAGS:
            found = None
            if self.stack:
                found = self.stack.pop()
            else:
                expected = _CONTROL_FLOW_END_TAGS[tag.block_type_name]
                dbt.exceptions.raise_compiler_error(
                    (
                        "Got an unexpected control flow end tag, got {} but "
                        "never saw a preceeding {} (@ {})"
                    ).format(tag.block_type_name, expected, tag.start)
                )
            expected = _CONTROL_FLOW_TAGS[found]
            if expected != tag.block_type_name:
                dbt.exceptions.raise_compiler_error(
                    (
                        "Got an unexpected control flow end tag, got {} but "
                        "expected {} next (@ {})"
                    ).format(tag.block_type_name, expected, tag.start)
                )

        if tag.block_type_name in allowed_blocks:
            if self.stack:
                dbt.exceptions.raise_compiler_error(
                    (
                        "Got a block definition inside control flow at {}. "
                        "All dbt block definitions must be at the top level"
                    ).format(tag.start)
                )
            if self.current is not None:
                dbt.exceptions.raise_compiler_error(
                    duplicate_tags.format(outer=self.current, inner=tag)
                )
            if collect_raw_data:
                raw_data = self.data[self.last_position : tag.start]
                self.last_position = tag.start
                if raw_data:
                    yield BlockData(raw_data)
            self.current = tag

        elif self.is_current_end(tag):
            self.last_position = tag.end
            yield BlockTag(
                block_type_name=self.current.block_type_name,
                block_name=self.current.block_name,
                contents=self.data[self.current.end : tag.start],
                full_block=self.data[self.current.start : tag.end],
            )
            self.current = None

    if self.current:
        linecount = self.data[: self.current.end].count("\n") + 1
        dbt.exceptions.raise_compiler_error(
            (
                "Reached EOF without finding a close tag for {} (searched from line {})"
            ).format(self.current.block_type_name, linecount)
        )

    if collect_raw_data:
        raw_data = self.data[self.last_position :]
        if raw_data:
            yield BlockData(raw_data)