Skip to content

Commit

Permalink
better error handling (#494)
Browse files Browse the repository at this point in the history
  • Loading branch information
cmcarthur authored Jul 26, 2017
1 parent 8d8a7fb commit a37374d
Show file tree
Hide file tree
Showing 28 changed files with 298 additions and 219 deletions.
5 changes: 3 additions & 2 deletions dbt/adapters/bigquery.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from contextlib import contextmanager

import dbt.compat
import dbt.exceptions
import dbt.flags as flags
import dbt.clients.gcloud
Expand Down Expand Up @@ -31,7 +32,7 @@ def handle_error(cls, error, message, sql):
logger.debug(message.format(sql=sql))
logger.debug(error)
error_msg = "\n".join([error['message'] for error in error.errors])
raise dbt.exceptions.RuntimeException(error_msg)
raise dbt.exceptions.DatabaseException(error_msg)

@classmethod
@contextmanager
Expand All @@ -51,7 +52,7 @@ def exception_handler(cls, profile, sql, model_name=None,
except Exception as e:
logger.debug("Unhandled error while running:\n{}".format(sql))
logger.debug(e)
raise dbt.exceptions.RuntimeException(e)
raise dbt.exceptions.RuntimeException(dbt.compat.to_string(e))

@classmethod
def type(cls):
Expand Down
1 change: 1 addition & 0 deletions dbt/adapters/default.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class DefaultAdapter(object):
"get_status",
"get_result_from_cursor",
"quote",
"quote_schema_and_table",
]

###
Expand Down
6 changes: 4 additions & 2 deletions dbt/adapters/postgres.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from contextlib import contextmanager

import dbt.adapters.default
import dbt.compat
import dbt.exceptions

from dbt.logger import GLOBAL_LOGGER as logger
Expand All @@ -23,13 +24,14 @@ def exception_handler(cls, profile, sql, model_name=None,
logger.debug('Postgres error: {}'.format(str(e)))

cls.rollback(connection)
raise dbt.exceptions.RuntimeException(e)
raise dbt.exceptions.DatabaseException(
dbt.compat.to_string(e).strip())

except Exception as e:
logger.debug("Error running SQL: %s", sql)
logger.debug("Rolling back transaction.")
cls.rollback(connection)
raise e
raise dbt.exceptions.RuntimeException(e)

@classmethod
def type(cls):
Expand Down
1 change: 0 additions & 1 deletion dbt/adapters/redshift.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

from dbt.adapters.postgres import PostgresAdapter
from dbt.logger import GLOBAL_LOGGER as logger # noqa
from dbt.compat import basestring


drop_lock = multiprocessing.Lock()
Expand Down
15 changes: 9 additions & 6 deletions dbt/adapters/snowflake.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

from contextlib import contextmanager

import dbt.compat
import dbt.exceptions
import dbt.flags as flags

Expand All @@ -26,26 +27,28 @@ def exception_handler(cls, profile, sql, model_name=None,
try:
yield
except snowflake.connector.errors.ProgrammingError as e:
logger.debug('Snowflake error: {}'.format(str(e)))
msg = dbt.compat.to_string(e)

if 'Empty SQL statement' in e.msg:
logger.debug('Snowflake error: {}'.format(msg))

if 'Empty SQL statement' in msg:
logger.debug("got empty sql statement, moving on")
elif 'This session does not have a current database' in e.msg:
elif 'This session does not have a current database' in msg:
cls.rollback(connection)
raise dbt.exceptions.FailedToConnectException(
('{}\n\nThis error sometimes occurs when invalid '
'credentials are provided, or when your default role '
'does not have access to use the specified database. '
'Please double check your profile and try again.')
.format(str(e)))
.format(msg))
else:
cls.rollback(connection)
raise dbt.exceptions.ProgrammingException(str(e))
raise dbt.exceptions.DatabaseException(msg)
except Exception as e:
logger.debug("Error running SQL: %s", sql)
logger.debug("Rolling back transaction.")
cls.rollback(connection)
raise e
raise dbt.exceptions.RuntimeException(e.msg)

@classmethod
def type(cls):
Expand Down
12 changes: 6 additions & 6 deletions dbt/clients/jinja.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,12 @@ def call(*args, **kwargs):

try:
return macro(*args, **kwargs)
except (jinja2.exceptions.TemplateRuntimeError) as e:
raise dbt.exceptions.MacroRuntimeException(
except (TypeError,
jinja2.exceptions.TemplateRuntimeError) as e:
dbt.exceptions.raise_compiler_error(
str(e),
context.get('model'),
node)
except dbt.exceptions.MacroRuntimeException as e:
except dbt.exceptions.CompilationException as e:
e.stack.append(node)
raise e

Expand Down Expand Up @@ -148,7 +148,7 @@ def get_template(string, ctx, node=None, capture_macros=False):
except (jinja2.exceptions.TemplateSyntaxError,
jinja2.exceptions.UndefinedError) as e:
e.translated = False
dbt.exceptions.raise_compiler_error(node, str(e))
dbt.exceptions.raise_compiler_error(str(e), node)


def render_template(template, ctx, node=None):
Expand All @@ -158,7 +158,7 @@ def render_template(template, ctx, node=None):
except (jinja2.exceptions.TemplateSyntaxError,
jinja2.exceptions.UndefinedError) as e:
e.translated = False
dbt.exceptions.raise_compiler_error(node, str(e))
dbt.exceptions.raise_compiler_error(str(e), node)


def get_rendered(string, ctx, node=None,
Expand Down
22 changes: 12 additions & 10 deletions dbt/context/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,23 +176,23 @@ def pretty_dict(self, data):
def assert_var_defined(self, var_name, default):
if var_name not in self.local_vars and default is None:
pretty_vars = self.pretty_dict(self.local_vars)
dbt.utils.compiler_error(
self.model,
dbt.exceptions.raise_compiler_error(
self.UndefinedVarError.format(
var_name, self.model_name, pretty_vars
)
),
self.model
)

def assert_var_not_none(self, var_name):
raw = self.local_vars[var_name]
if raw is None:
pretty_vars = self.pretty_dict(self.local_vars)
model_name = dbt.utils.get_model_name_or_none(self.model)
dbt.utils.compiler_error(
self.model,
dbt.exceptions.raise_compiler_error(
self.NoneVarError.format(
var_name, model_name, pretty_vars
)
),
self.model
)

def __call__(self, var_name, default=None):
Expand All @@ -214,7 +214,9 @@ def __call__(self, var_name, default=None):

def write(node, target_path, subdirectory):
def fn(payload):
dbt.writer.write_node(node, target_path, subdirectory, payload)
node['build_path'] = dbt.writer.write_node(
node, target_path, subdirectory, payload)

return fn


Expand Down Expand Up @@ -273,9 +275,7 @@ def generate(model, project, flat_graph, provider=None):
schema,
dbt.utils.model_immediate_name(model, dbt.flags.NON_DESTRUCTIVE),
model.get('name')
),
"var": Var(model, context=context),
"write": write(model, project.get('target-path'), 'run'),
)
})

context = _add_tracking(context)
Expand All @@ -286,7 +286,9 @@ def generate(model, project, flat_graph, provider=None):

context = _add_macros(context, model, flat_graph)

context["write"] = write(model, project.get('target-path'), 'run')
context["render"] = render(context, model)
context["var"] = Var(model, context=context)
context['context'] = context

return context
6 changes: 3 additions & 3 deletions dbt/context/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ def __call__(self, *args, **kwargs):
elif len(args) == 0 and len(kwargs) > 0:
opts = kwargs
else:
dbt.utils.compiler_error(
self.model.get('name'),
"Invalid model config given inline in {}".format(self.model))
dbt.exceptions.raise_compiler_error(
"Invalid inline model config",
self.model)

self.model['config_reference'].update_in_model_config(opts)
return ''
Expand Down
6 changes: 4 additions & 2 deletions dbt/context/runtime.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import json

from dbt.adapters.factory import get_adapter
from dbt.compat import basestring

import dbt.clients.jinja
import dbt.context.common
import dbt.flags
import dbt.utils

import dbt.context.common

from dbt.logger import GLOBAL_LOGGER as logger # noqa


Expand Down
13 changes: 0 additions & 13 deletions dbt/contracts/graph/parsed.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,23 +72,10 @@
def validate_nodes(parsed_nodes):
validate_with(parsed_nodes_contract, parsed_nodes)

[validate_incremental(node) for unique_id, node
in parsed_nodes.items()]


def validate_macros(parsed_macros):
validate_with(parsed_macros_contract, parsed_macros)


def validate(parsed_graph):
validate_with(parsed_graph_contract, parsed_graph)

[validate_incremental(node) for unique_id, node
in parsed_graph.get('nodes').items()]


def validate_incremental(node):
if(node.get('resource_type') == NodeType.Model and
get_materialization(node) == 'incremental' and
node.get('config', {}).get('sql_where') is None):
dbt.exceptions.missing_sql_where(node)
1 change: 1 addition & 0 deletions dbt/contracts/graph/unparsed.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
# filesystem
Required('root_path'): basestring,
Required('path'): basestring,
Required('original_file_path'): basestring,
Required('raw_sql'): basestring,
})

Expand Down
Loading

0 comments on commit a37374d

Please sign in to comment.