Skip to content

Commit

Permalink
Merge pull request #1000 from fishtown-analytics/fix/exception-handli…
Browse files Browse the repository at this point in the history
…ng-errors

Fix exception handling masking on cleanup (#997)
  • Loading branch information
beckjake authored Sep 18, 2018
2 parents 1c67d19 + 22d4a1d commit 5fc97bc
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 4 deletions.
3 changes: 2 additions & 1 deletion dbt/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@ def __str__(self, prefix="! "):
if hasattr(self.msg, 'split'):
split_msg = self.msg.split("\n")
else:
split_msg = basestring(self.msg).split("\n")
# can't use basestring here, as on python2 it's an abstract class
split_msg = str(self.msg).split("\n")

lines = ["{}{}".format(self.type + ' Error',
node_string)] + split_msg
Expand Down
38 changes: 35 additions & 3 deletions dbt/node_runners.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@
import dbt.templates
import dbt.writer

import six
import sys
import time
import traceback


INTERNAL_ERROR_STRING = """This is an error in dbt. Please try again. If \
Expand Down Expand Up @@ -73,6 +76,7 @@ def safe_run(self, manifest):

result = RunModelResult(self.node)
started = time.time()
exc_info = (None, None, None)

try:
# if we fail here, we still have a compiled node to return
Expand Down Expand Up @@ -105,23 +109,51 @@ def safe_run(self, manifest):
result.status = 'ERROR'

except Exception as e:
# set this here instead of finally, as python 2/3 exc_info()
# behavior with re-raised exceptions are slightly different
exc_info = sys.exc_info()
prefix = "Unhandled error while executing {filepath}".format(
filepath=self.node.build_path)

error = "{prefix}\n{error}".format(
prefix=dbt.ui.printer.red(prefix),
error=str(e).strip())

logger.debug(error)
logger.error(error)
raise e

finally:
node_name = self.node.name
self.adapter.release_connection(self.config, node_name)
exc_str = self._safe_release_connection()

# if we had an unhandled exception, re-raise it
if exc_info and exc_info[1]:
six.reraise(*exc_info)

# if releasing failed and the result doesn't have an error yet, set
# an error
if exc_str is not None and result.error is None:
result.error = exc_str
result.status = 'ERROR'

result.execution_time = time.time() - started
return result

def _safe_release_connection(self):
"""Try to release a connection. If an exception is hit, log and return
the error string.
"""
node_name = self.node.name
try:
self.adapter.release_connection(self.config, node_name)
except Exception as exc:
logger.debug(
'Error releasing connection for node {}: {!s}\n{}'
.format(node_name, exc, traceback.format_exc())
)
return dbt.compat.to_string(exc)

return None

def before_execute(self):
raise NotImplementedException()

Expand Down

0 comments on commit 5fc97bc

Please sign in to comment.