# Buggy code
def node_to_string(self, node):
    if node is None:
        return "<Unknown>"
    if not hasattr(node, "name"):
        # we probably failed to parse a block, so we can't know the name
        return "{} ({})".format(node.resource_type, node.original_file_path)
    return "{} {} ({})".format(node.resource_type, node.name, node.original_file_path)


# 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 node_to_string(self, node):
    if node is None:
        return "<Unknown>"
    if not hasattr(node, "name"):
        # we probably failed to parse a block, so we can't know the name
        return "{} ({})".format(node.resource_type, node.original_file_path)

    if hasattr(node, "contents"):
        # handle FileBlocks. They aren't really nodes but we want to render
        # out the path we know at least. This indicates an error during
        # block parsing.
        return "{}".format(node.path.original_file_path)
    return "{} {} ({})".format(node.resource_type, node.name, node.original_file_path)