Compare commits

...

2 Commits

Author SHA1 Message Date
Emily Rockman
ad9aabca1d fix merge conflict leftovers 2022-11-29 09:25:42 -06:00
Emily Rockman
ea1304f8bb WIP
WIP

WIP

WIP

WIP

added data to exception

log all class props

WIP
2022-11-29 08:17:39 -06:00
22 changed files with 434 additions and 129 deletions

View File

@@ -14,7 +14,7 @@ from dbt.exceptions import DbtProfileError
from dbt.exceptions import DbtProjectError from dbt.exceptions import DbtProjectError
from dbt.exceptions import ValidationException from dbt.exceptions import ValidationException
from dbt.exceptions import RuntimeException from dbt.exceptions import RuntimeException
from dbt.exceptions import validator_error_message from dbt.exception_messages import validator_error_message
from dbt.events.types import MissingProfileTarget from dbt.events.types import MissingProfileTarget
from dbt.events.functions import fire_event from dbt.events.functions import fire_event
from dbt.utils import coerce_dict_str from dbt.utils import coerce_dict_str

View File

@@ -21,9 +21,9 @@ from dbt.clients.system import path_exists
from dbt.clients.system import load_file_contents from dbt.clients.system import load_file_contents
from dbt.clients.yaml_helper import load_yaml_text from dbt.clients.yaml_helper import load_yaml_text
from dbt.contracts.connection import QueryComment from dbt.contracts.connection import QueryComment
from dbt.exception_messages import validator_error_message
from dbt.exceptions import DbtProjectError from dbt.exceptions import DbtProjectError
from dbt.exceptions import SemverException from dbt.exceptions import SemverException
from dbt.exceptions import validator_error_message
from dbt.exceptions import RuntimeException from dbt.exceptions import RuntimeException
from dbt.graph import SelectionSpec from dbt.graph import SelectionSpec
from dbt.helper_types import NoValue from dbt.helper_types import NoValue

View File

@@ -24,11 +24,11 @@ from dbt.contracts.graph.manifest import ManifestMetadata
from dbt.contracts.project import Configuration, UserConfig from dbt.contracts.project import Configuration, UserConfig
from dbt.contracts.relation import ComponentName from dbt.contracts.relation import ComponentName
from dbt.dataclass_schema import ValidationError from dbt.dataclass_schema import ValidationError
from dbt.exception_messages import validator_error_message
from dbt.exceptions import ( from dbt.exceptions import (
DbtProjectError, DbtProjectError,
RuntimeException, RuntimeException,
raise_compiler_error, raise_compiler_error,
validator_error_message,
) )
from dbt.events.functions import warn_or_error from dbt.events.functions import warn_or_error
from dbt.events.types import UnusedResourceConfigPath from dbt.events.types import UnusedResourceConfigPath

View File

@@ -31,7 +31,7 @@ class DBTDeprecation:
except AttributeError: except AttributeError:
msg = f"Event Class `{class_name}` is not defined in `{module_path}`" msg = f"Event Class `{class_name}` is not defined in `{module_path}`"
raise NameError(msg) raise NameError(msg)
raise NotImplementedError("event not implemented for {}".format(self._event)) raise NotImplementedError("event not implemented for {}".format(self))
def show(self, *args, **kwargs) -> None: def show(self, *args, **kwargs) -> None:
if self.name not in active_deprecations: if self.name not in active_deprecations:

237
core/dbt/deps/exceptions.py Normal file
View File

@@ -0,0 +1,237 @@
import abc
import builtins
from typing import ClassVar, NoReturn, Dict
import dbt.events
from dbt.events.helpers import env_secrets, scrub_secrets
# TODO: using this special case here to not break the rest of exceptions but this would normally
# live centrally
class Exception(builtins.Exception):
CODE = -32000
MESSAGE = "Server Error"
_event: ClassVar[str] = "GeneralException"
_category: str = "general exception"
def __init__(self):
super().__init__()
self.log()
def data(self) -> Dict[str, str]:
# do not override
constant_exception_data = {
"type": self.__class__.__name__, # is this used outside logbook logs?
"message": str(self),
"event": self._event, # does not always match type
"category": self._category,
}
# TODO: can't guarantee this is always serializable...
return {**constant_exception_data, **vars(self)}
@property
def event(self) -> abc.ABCMeta:
if self._event is not None:
module_path = dbt.events.types
class_name = self._event
try:
return getattr(module_path, class_name)
except AttributeError:
msg = f"Event Class `{class_name}` is not defined in `{module_path}`"
raise NameError(msg)
raise NotImplementedError("event not implemented for {}".format(self))
def log(self, *args, **kwargs) -> None:
log_event = self.event(data=self.data(), **kwargs)
dbt.events.functions.fire_event(log_event)
class RuntimeException(RuntimeError, Exception):
CODE = 10001
MESSAGE = "Runtime error"
def __init__(self, msg, node=None):
self.stack = []
self.node = node
self.message = scrub_secrets(msg, env_secrets())
def add_node(self, node=None):
if node is not None and node is not self.node:
if self.node is not None:
self.stack.append(self.node)
self.node = node
@property
def type(self):
return "Runtime"
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)
def process_stack(self):
lines = []
stack = self.stack + [self.node]
first = True
if len(stack) > 1:
lines.append("")
for item in stack:
msg = "called by"
if first:
msg = "in"
first = False
lines.append("> {} {}".format(msg, self.node_to_string(item)))
return lines
def __str__(self, prefix="! "):
node_string = ""
if self.node is not None:
node_string = " in {}".format(self.node_to_string(self.node))
if hasattr(self.message, "split"):
split_msg = self.message.split("\n")
else:
split_msg = str(self.message).split("\n")
lines = ["{}{}".format(self.type + " Error", node_string)] + split_msg
lines += self.process_stack()
return lines[0] + "\n" + "\n".join([" " + line for line in lines[1:]])
def data(self):
result = Exception.data(self)
if self.node is None:
return result
result.update(
{
"raw_code": self.node.raw_code,
# the node isn't always compiled, but if it is, include that!
"compiled_code": getattr(self.node, "compiled_code", None),
}
)
return result
# TODO: caused some circular imports. copied here. doesn't belong here.
class CommandError(RuntimeException):
def __init__(self, cwd, cmd, message="Error running command"):
cmd_scrubbed = list(scrub_secrets(cmd_txt, env_secrets()) for cmd_txt in cmd)
super().__init__(message)
self.cwd = cwd
self.cmd = cmd_scrubbed
self.args = (cwd, cmd_scrubbed, message)
def __str__(self):
if len(self.cmd) == 0:
return "{}: No arguments given".format(self.message)
return '{}: "{}"'.format(self.message, self.cmd[0])
# Start actual deps exceptions
class DependencyException(Exception):
# this can happen due to raise_dependency_error and its callers
CODE = 10006
MESSAGE = "Dependency Error"
_event: ClassVar[str] = "DependencyException"
_category: str = "general deps"
def __init__(self, message):
super().__init__()
self.message = scrub_secrets(message, env_secrets())
# TODO: explore where this should live
class ExecutableError(CommandError):
def __init__(self, cwd, cmd, message):
super().__init__(cwd, cmd, message)
class InternalException(DependencyException):
_category: str = "internal"
# This was using SemverException previously...
class DependencyVersionException(DependencyException):
_category: str = "version"
def __init__(self, name):
self.name = name
msg = "Version error for package {}: {}".format(self.name, self)
super().__init__(msg)
class MultipleDependencyVersionException(DependencyException):
_category: str = "git"
def __init__(self, git, requested):
self.git = git
self.requested = requested
msg = "git dependencies should contain exactly one version. " "{} contains: {}".format(
self.git, requested
)
super().__init__(msg)
class PackageNotFound(DependencyException):
def __init__(self, package_name):
self.package_name = package_name
msg = f"Package {self.package_name} was not found in the package index"
super().__init__(msg)
class PackageVersionNotFound(DependencyException):
_category: str = "config"
def __init__(self, package_name, version_range, available_versions, should_version_check):
self.package_name = package_name
self.version_range = str(version_range)
self.available_versions = available_versions
self.should_version_check = should_version_check
msg = self.build_msg()
super().__init__(msg)
def build_msg(self):
base_msg = (
"Could not find a matching compatible version for package {}\n"
" Requested range: {}\n"
" Compatible versions: {}\n"
)
addendum = (
(
"\n"
" Not shown: package versions incompatible with installed version of dbt-core\n"
" To include them, run 'dbt --no-version-check deps'"
)
if self.should_version_check
else ""
)
return (
base_msg.format(self.package_name, self.version_range, self.available_versions)
+ addendum
)
# should these all become their own exceptions? They have to all share a category if not.
def raise_dependency_error(msg) -> NoReturn:
raise DependencyException(scrub_secrets(msg, env_secrets()))

View File

@@ -9,7 +9,7 @@ from dbt.contracts.project import (
GitPackage, GitPackage,
) )
from dbt.deps.base import PinnedPackage, UnpinnedPackage, get_downloads_path from dbt.deps.base import PinnedPackage, UnpinnedPackage, get_downloads_path
from dbt.exceptions import ExecutableError, raise_dependency_error from .exceptions import ExecutableError, MultipleDependencyVersionException
from dbt.events.functions import fire_event, warn_or_error from dbt.events.functions import fire_event, warn_or_error
from dbt.events.types import EnsureGitInstalled, DepsUnpinned from dbt.events.types import EnsureGitInstalled, DepsUnpinned
@@ -143,10 +143,7 @@ class GitUnpinnedPackage(GitPackageMixin, UnpinnedPackage[GitPinnedPackage]):
if len(requested) == 0: if len(requested) == 0:
requested = {"HEAD"} requested = {"HEAD"}
elif len(requested) > 1: elif len(requested) > 1:
raise_dependency_error( raise MultipleDependencyVersionException(git=self.git, requested=requested)
"git dependencies should contain exactly one version. "
"{} contains: {}".format(self.git, requested)
)
return GitPinnedPackage( return GitPinnedPackage(
git=self.git, git=self.git,

View File

@@ -11,11 +11,13 @@ from dbt.contracts.project import (
RegistryPackage, RegistryPackage,
) )
from dbt.deps.base import PinnedPackage, UnpinnedPackage, get_downloads_path from dbt.deps.base import PinnedPackage, UnpinnedPackage, get_downloads_path
from dbt.exceptions import ( from dbt.deps.exceptions import (
package_version_not_found, DependencyVersionException,
VersionsNotCompatibleException, )
DependencyException, from dbt.exceptions import VersionsNotCompatibleException
package_not_found, from .exceptions import (
PackageVersionNotFound,
PackageNotFound,
) )
from dbt.utils import _connection_exception_retry as connection_exception_retry from dbt.utils import _connection_exception_retry as connection_exception_retry
@@ -99,7 +101,7 @@ class RegistryUnpinnedPackage(RegistryPackageMixin, UnpinnedPackage[RegistryPinn
def _check_in_index(self): def _check_in_index(self):
index = registry.index_cached() index = registry.index_cached()
if self.package not in index: if self.package not in index:
package_not_found(self.package) raise PackageNotFound(self.package)
@classmethod @classmethod
def from_contract(cls, contract: RegistryPackage) -> "RegistryUnpinnedPackage": def from_contract(cls, contract: RegistryPackage) -> "RegistryUnpinnedPackage":
@@ -124,8 +126,7 @@ class RegistryUnpinnedPackage(RegistryPackageMixin, UnpinnedPackage[RegistryPinn
try: try:
range_ = semver.reduce_versions(*self.versions) range_ = semver.reduce_versions(*self.versions)
except VersionsNotCompatibleException as e: except VersionsNotCompatibleException as e:
new_msg = "Version error for package {}: {}".format(self.name, e) raise DependencyVersionException(self.name) from e
raise DependencyException(new_msg) from e
should_version_check = bool(flags.VERSION_CHECK) should_version_check = bool(flags.VERSION_CHECK)
dbt_version = get_installed_version() dbt_version = get_installed_version()
@@ -146,7 +147,12 @@ class RegistryUnpinnedPackage(RegistryPackageMixin, UnpinnedPackage[RegistryPinn
target = None target = None
if not target: if not target:
# raise an exception if no installable target version is found # raise an exception if no installable target version is found
package_version_not_found(self.package, range_, installable, should_version_check) raise PackageVersionNotFound(
package_name=self.package,
version_range=range_,
available_versions=installable,
should_version_check=should_version_check,
)
latest_compatible = installable[-1] latest_compatible = installable[-1]
return RegistryPinnedPackage( return RegistryPinnedPackage(
package=self.package, version=target, version_latest=latest_compatible package=self.package, version=target, version_latest=latest_compatible

View File

@@ -1,7 +1,7 @@
from dataclasses import dataclass, field from dataclasses import dataclass, field
from typing import Dict, List, NoReturn, Union, Type, Iterator, Set from typing import Dict, List, NoReturn, Union, Type, Iterator, Set
from dbt.exceptions import raise_dependency_error, InternalException from .exceptions import raise_dependency_error, InternalException
from dbt.config import Project, RuntimeConfig from dbt.config import Project, RuntimeConfig
from dbt.config.renderer import DbtProjectYamlRenderer from dbt.config.renderer import DbtProjectYamlRenderer

View File

@@ -1495,6 +1495,16 @@ class NoNodesForSelectionCriteria(betterproto.Message):
spec_raw: str = betterproto.string_field(2) spec_raw: str = betterproto.string_field(2)
@dataclass
class DependencyException(betterproto.Message):
"""M031"""
info: "EventInfo" = betterproto.message_field(1)
data: Dict[str, str] = betterproto.map_field(
3, betterproto.TYPE_STRING, betterproto.TYPE_STRING
)
@dataclass @dataclass
class RunningOperationCaughtError(betterproto.Message): class RunningOperationCaughtError(betterproto.Message):
"""Q001""" """Q001"""
@@ -1827,6 +1837,13 @@ class FoundStats(betterproto.Message):
stat_line: str = betterproto.string_field(2) stat_line: str = betterproto.string_field(2)
@dataclass
class GeneralException(betterproto.Message):
"""X001"""
info: "EventInfo" = betterproto.message_field(1)
@dataclass @dataclass
class MainKeyboardInterrupt(betterproto.Message): class MainKeyboardInterrupt(betterproto.Message):
"""Z001""" """Z001"""

View File

@@ -1136,6 +1136,12 @@ message NoNodesForSelectionCriteria {
string spec_raw = 2; string spec_raw = 2;
} }
// M031
message DependencyException {
EventInfo info = 1;
map<string, string> data = 3;
}
// Q - Node execution // Q - Node execution
// Q001 // Q001
@@ -1416,6 +1422,14 @@ message FoundStats {
string stat_line = 2; string stat_line = 2;
} }
// X - Exceptions
//X001
message GeneralException {
EventInfo info = 1;
}
// Z - Misc // Z - Misc
// Z001 // Z001

View File

@@ -18,6 +18,7 @@ from dbt.events.format import format_fancy_output_line, pluralize
from dbt.events.proto_types import EventInfo, RunResultMsg, ListOfStrings # noqa from dbt.events.proto_types import EventInfo, RunResultMsg, ListOfStrings # noqa
from dbt.events.proto_types import NodeInfo, ReferenceKeyMsg # noqa from dbt.events.proto_types import NodeInfo, ReferenceKeyMsg # noqa
from dbt.events import proto_types as pt from dbt.events import proto_types as pt
from dbt.exception_messages import get_not_found_or_disabled_msg_2
from dbt.node_types import NodeType from dbt.node_types import NodeType
@@ -40,6 +41,7 @@ from dbt.node_types import NodeType
# | M | Deps generation | # | M | Deps generation |
# | Q | Node execution | # | Q | Node execution |
# | W | Node testing | # | W | Node testing |
# | X | Exceptions |
# | Z | Misc | # | Z | Misc |
# | T | Test only | # | T | Test only |
# #
@@ -1491,28 +1493,14 @@ class NodeNotFoundOrDisabled(WarnLevel, pt.NodeNotFoundOrDisabled):
return "I060" return "I060"
def message(self) -> str: def message(self) -> str:
# this is duplicated logic from exceptions.get_not_found_or_disabled_msg msg = get_not_found_or_disabled_msg_2(
# when we convert exceptions to be stuctured maybe it can be combined? original_file_path=self.original_file_path,
# convverting the bool to a string since None is also valid unique_id=self.unique_id,
if self.disabled == "None": resource_type_title=self.resource_type_title,
reason = "was not found or is disabled" target_name=self.target_name,
elif self.disabled == "True": target_kind=self.target_kind,
reason = "is disabled" target_package=self.target_package,
else: disabled=self.disabled,
reason = "was not found"
target_package_string = ""
if self.target_package is not None:
target_package_string = "in package '{}' ".format(self.target_package)
msg = "{} '{}' ({}) depends on a {} named '{}' {}which {}".format(
self.resource_type_title,
self.unique_id,
self.original_file_path,
self.target_kind,
self.target_name,
target_package_string,
reason,
) )
return warning_tag(msg) return warning_tag(msg)
@@ -1824,6 +1812,15 @@ class NoNodesForSelectionCriteria(WarnLevel, pt.NoNodesForSelectionCriteria):
return f"The selection criterion '{self.spec_raw}' does not match any nodes" return f"The selection criterion '{self.spec_raw}' does not match any nodes"
@dataclass
class DependencyException(ErrorLevel, pt.DependencyException):
def code(self):
return "M031"
def message(self) -> str:
return f"This is the custom message: {self.data.get('message')}"
# ======================================================= # =======================================================
# Q - Node execution # Q - Node execution
# ======================================================= # =======================================================
@@ -2298,6 +2295,20 @@ class FoundStats(InfoLevel, pt.FoundStats):
return f"Found {self.stat_line}" return f"Found {self.stat_line}"
# =======================================================
# X - Exceptions
# =======================================================
@dataclass
class GeneralException(ErrorLevel, pt.GeneralException):
def code(self):
return "X001"
def message(self) -> str:
return "General Exception"
# ======================================================= # =======================================================
# Z - Misc # Z - Misc
# ======================================================= # =======================================================

View File

@@ -0,0 +1,75 @@
import dbt.dataclass_schema
from typing import Optional
def validator_error_message(exc):
"""Given a dbt.dataclass_schema.ValidationError (which is basically a
jsonschema.ValidationError), return the relevant parts as a string
"""
if not isinstance(exc, dbt.dataclass_schema.ValidationError):
return str(exc)
path = "[%s]" % "][".join(map(repr, exc.relative_path))
return "at path {}: {}".format(path, exc.message)
def get_not_found_or_disabled_msg(
original_file_path,
unique_id,
resource_type_title,
target_name: str,
target_kind: str,
target_package: Optional[str] = None,
disabled: Optional[bool] = None,
) -> str:
if disabled is None:
reason = "was not found or is disabled"
elif disabled is True:
reason = "is disabled"
else:
reason = "was not found"
target_package_string = ""
if target_package is not None:
target_package_string = "in package '{}' ".format(target_package)
return "{} '{}' ({}) depends on a {} named '{}' {}which {}".format(
resource_type_title,
unique_id,
original_file_path,
target_kind,
target_name,
target_package_string,
reason,
)
# TODO: temp fix for mypy/proto sanity - combine later
def get_not_found_or_disabled_msg_2(
original_file_path,
unique_id,
resource_type_title,
target_name: str,
target_kind: str,
disabled: str,
target_package: Optional[str] = None,
) -> str:
if disabled == "None":
reason = "was not found or is disabled"
elif disabled == "True":
reason = "is disabled"
else:
reason = "was not found"
target_package_string = ""
if target_package is not None:
target_package_string = "in package '{}' ".format(target_package)
return "{} '{}' ({}) depends on a {} named '{}' {}which {}".format(
resource_type_title,
unique_id,
original_file_path,
target_kind,
target_name,
target_package_string,
reason,
)

View File

@@ -1,24 +1,15 @@
import builtins import builtins
import functools import functools
from typing import NoReturn, Optional, Mapping, Any from typing import Any, Mapping, NoReturn, Optional
from dbt.events.helpers import env_secrets, scrub_secrets from dbt.events.helpers import env_secrets, scrub_secrets
from dbt.events.types import JinjaLogWarning from dbt.events.types import JinjaLogWarning
from dbt.exception_messages import get_not_found_or_disabled_msg
from dbt.node_types import NodeType from dbt.node_types import NodeType
import dbt.dataclass_schema import dbt.dataclass_schema
def validator_error_message(exc):
"""Given a dbt.dataclass_schema.ValidationError (which is basically a
jsonschema.ValidationError), return the relevant parts as a string
"""
if not isinstance(exc, dbt.dataclass_schema.ValidationError):
return str(exc)
path = "[%s]" % "][".join(map(repr, exc.relative_path))
return "at path {}: {}".format(path, exc.message)
class Exception(builtins.Exception): class Exception(builtins.Exception):
CODE = -32000 CODE = -32000
MESSAGE = "Server Error" MESSAGE = "Server Error"
@@ -309,12 +300,6 @@ class AliasException(ValidationException):
pass pass
class DependencyException(Exception):
# this can happen due to raise_dependency_error and its callers
CODE = 10006
MESSAGE = "Dependency Error"
class DbtConfigError(RuntimeException): class DbtConfigError(RuntimeException):
CODE = 10007 CODE = 10007
MESSAGE = "DBT Configuration Error" MESSAGE = "DBT Configuration Error"
@@ -451,10 +436,6 @@ def raise_database_error(msg, node=None) -> NoReturn:
raise DatabaseException(msg, node) raise DatabaseException(msg, node)
def raise_dependency_error(msg) -> NoReturn:
raise DependencyException(scrub_secrets(msg, env_secrets()))
def raise_git_cloning_error(error: CommandResultError) -> NoReturn: def raise_git_cloning_error(error: CommandResultError) -> NoReturn:
error.cmd = scrub_secrets(str(error.cmd), env_secrets()) error.cmd = scrub_secrets(str(error.cmd), env_secrets())
raise error raise error
@@ -568,37 +549,6 @@ def doc_target_not_found(
raise_compiler_error(msg, model) raise_compiler_error(msg, model)
def get_not_found_or_disabled_msg(
original_file_path,
unique_id,
resource_type_title,
target_name: str,
target_kind: str,
target_package: Optional[str] = None,
disabled: Optional[bool] = None,
) -> str:
if disabled is None:
reason = "was not found or is disabled"
elif disabled is True:
reason = "is disabled"
else:
reason = "was not found"
target_package_string = ""
if target_package is not None:
target_package_string = "in package '{}' ".format(target_package)
return "{} '{}' ({}) depends on a {} named '{}' {}which {}".format(
resource_type_title,
unique_id,
original_file_path,
target_kind,
target_name,
target_package_string,
reason,
)
def target_not_found( def target_not_found(
node, node,
target_name: str, target_name: str,
@@ -718,31 +668,6 @@ def relation_wrong_type(relation, expected_type, model=None):
) )
def package_not_found(package_name):
raise_dependency_error("Package {} was not found in the package index".format(package_name))
def package_version_not_found(
package_name, version_range, available_versions, should_version_check
):
base_msg = (
"Could not find a matching compatible version for package {}\n"
" Requested range: {}\n"
" Compatible versions: {}\n"
)
addendum = (
(
"\n"
" Not shown: package versions incompatible with installed version of dbt-core\n"
" To include them, run 'dbt --no-version-check deps'"
)
if should_version_check
else ""
)
msg = base_msg.format(package_name, version_range, available_versions) + addendum
raise_dependency_error(msg)
def invalid_materialization_argument(name, argument): def invalid_materialization_argument(name, argument):
raise_compiler_error( raise_compiler_error(
"materialization '{}' received unknown argument '{}'.".format(name, argument) "materialization '{}' received unknown argument '{}'.".format(name, argument)
@@ -1000,6 +925,9 @@ def warn(msg, node=None):
return "" return ""
# TODO: importing here just to track things separately
from dbt.deps.exceptions import raise_dependency_error # noqa
# Update this when a new function should be added to the # Update this when a new function should be added to the
# dbt context's `exceptions` key! # dbt context's `exceptions` key!
CONTEXT_EXPORTS = { CONTEXT_EXPORTS = {

View File

@@ -18,7 +18,8 @@ from dbt.context.context_config import ContextConfig
from dbt.contracts.graph.manifest import Manifest from dbt.contracts.graph.manifest import Manifest
from dbt.contracts.graph.parsed import HasUniqueID, ManifestNodes from dbt.contracts.graph.parsed import HasUniqueID, ManifestNodes
from dbt.contracts.graph.unparsed import UnparsedNode, Docs from dbt.contracts.graph.unparsed import UnparsedNode, Docs
from dbt.exceptions import ParsingException, validator_error_message, InternalException from dbt.exception_messages import validator_error_message
from dbt.exceptions import ParsingException, InternalException
from dbt import hooks from dbt import hooks
from dbt.node_types import NodeType, ModelLanguage from dbt.node_types import NodeType, ModelLanguage
from dbt.parser.search import FileBlock from dbt.parser.search import FileBlock

View File

@@ -978,7 +978,7 @@ def invalid_target_fail_unless_test(
target_name=target_name, target_name=target_name,
target_kind=target_kind, target_kind=target_kind,
target_package=target_package if target_package else "", target_package=target_package if target_package else "",
disabled=str(disabled), disabled="None" if disabled is None else str(disabled),
) )
) )
else: else:

View File

@@ -29,7 +29,8 @@ from typing import Any, Dict, Iterator, List, Optional, Tuple, Union
# New for Python models :p # New for Python models :p
import ast import ast
from dbt.dataclass_schema import ValidationError from dbt.dataclass_schema import ValidationError
from dbt.exceptions import ParsingException, validator_error_message, UndefinedMacroException from dbt.exception_messages import validator_error_message
from dbt.exceptions import ParsingException, UndefinedMacroException
dbt_function_key_words = set(["ref", "source", "config", "get"]) dbt_function_key_words = set(["ref", "source", "config", "get"])

View File

@@ -49,8 +49,8 @@ from dbt.contracts.graph.unparsed import (
UnparsedMetric, UnparsedMetric,
UnparsedSourceDefinition, UnparsedSourceDefinition,
) )
from dbt.exception_messages import validator_error_message
from dbt.exceptions import ( from dbt.exceptions import (
validator_error_message,
JSONValidationException, JSONValidationException,
raise_invalid_property_yml_version, raise_invalid_property_yml_version,
ValidationException, ValidationException,

View File

@@ -4,7 +4,8 @@ from typing import List
from dbt.dataclass_schema import ValidationError from dbt.dataclass_schema import ValidationError
from dbt.contracts.graph.parsed import IntermediateSnapshotNode, ParsedSnapshotNode from dbt.contracts.graph.parsed import IntermediateSnapshotNode, ParsedSnapshotNode
from dbt.exceptions import ParsingException, validator_error_message from dbt.exception_messages import validator_error_message
from dbt.exceptions import ParsingException
from dbt.node_types import NodeType from dbt.node_types import NodeType
from dbt.parser.base import SQLParser from dbt.parser.base import SQLParser
from dbt.parser.search import BlockContents, BlockSearcher, FileBlock from dbt.parser.search import BlockContents, BlockSearcher, FileBlock

View File

@@ -174,6 +174,7 @@ class ModelRunner(CompileRunner):
return f"{self.node.language} {self.node.get_materialization()} model {self.get_node_representation()}" return f"{self.node.language} {self.node.get_materialization()} model {self.get_node_representation()}"
def print_start_line(self): def print_start_line(self):
breakpoint()
fire_event( fire_event(
LogStartLine( LogStartLine(
description=self.describe_node(), description=self.describe_node(),

View File

@@ -4,7 +4,7 @@ import unittest
from unittest import mock from unittest import mock
import dbt.deps import dbt.deps
import dbt.exceptions import dbt.deps.exceptions
from dbt.deps.git import GitUnpinnedPackage from dbt.deps.git import GitUnpinnedPackage
from dbt.deps.local import LocalUnpinnedPackage from dbt.deps.local import LocalUnpinnedPackage
from dbt.deps.registry import RegistryUnpinnedPackage from dbt.deps.registry import RegistryUnpinnedPackage
@@ -92,7 +92,7 @@ class TestGitPackage(unittest.TestCase):
self.assertEqual(c.git, 'http://example.com') self.assertEqual(c.git, 'http://example.com')
self.assertEqual(c.revisions, ['0.0.1', '0.0.2']) self.assertEqual(c.revisions, ['0.0.1', '0.0.2'])
with self.assertRaises(dbt.exceptions.DependencyException): with self.assertRaises(dbt.deps.exceptions.DependencyException):
c.resolved() c.resolved()
def test_default_revision(self): def test_default_revision(self):
@@ -223,7 +223,7 @@ class TestHubPackage(unittest.TestCase):
package='dbt-labs-test/b', package='dbt-labs-test/b',
version='0.1.2' version='0.1.2'
)) ))
with self.assertRaises(dbt.exceptions.DependencyException) as exc: with self.assertRaises(dbt.deps.exceptions.PackageNotFound) as exc:
a.resolved() a.resolved()
msg = 'Package dbt-labs-test/b was not found in the package index' msg = 'Package dbt-labs-test/b was not found in the package index'
@@ -235,7 +235,7 @@ class TestHubPackage(unittest.TestCase):
version='0.1.4' version='0.1.4'
)) ))
with self.assertRaises(dbt.exceptions.DependencyException) as exc: with self.assertRaises(dbt.deps.exceptions.PackageVersionNotFound) as exc:
a.resolved() a.resolved()
msg = ( msg = (
"Could not find a matching compatible version for package " "Could not find a matching compatible version for package "
@@ -257,7 +257,7 @@ class TestHubPackage(unittest.TestCase):
b = RegistryUnpinnedPackage.from_contract(b_contract) b = RegistryUnpinnedPackage.from_contract(b_contract)
c = a.incorporate(b) c = a.incorporate(b)
with self.assertRaises(dbt.exceptions.DependencyException) as exc: with self.assertRaises(dbt.deps.exceptions.DependencyVersionException) as exc:
c.resolved() c.resolved()
msg = ( msg = (
"Version error for package dbt-labs-test/a: Could not " "Version error for package dbt-labs-test/a: Could not "

View File

@@ -80,8 +80,11 @@ class BaseAliasErrors:
def test_alias_dupe_thorews_exeption(self, project): def test_alias_dupe_thorews_exeption(self, project):
message = ".*identical database representation.*" message = ".*identical database representation.*"
with pytest.raises(Exception) as exc: with pytest.raises(Exception) as exc:
assert message in exc # assert message in exc
run_dbt(["run"]) run_dbt(["run"])
assert message in exc
# breakpoint()
# print("ab")
class BaseSameAliasDifferentSchemas: class BaseSameAliasDifferentSchemas:

View File

@@ -0,0 +1,13 @@
# flake8: noqa
import pytest
from dbt.exceptions import Exception
class TestBaseException:
def test_base_exception(self):
with pytest.raises(Exception) as exc_info:
raise(Exception())
breakpoint()
print("hi")