Example #1
0
    def _add_last_error_info(self, exc_info=None):
        ex = exc_info[1]

        if show_exc_info(ex):
            # if we are showing internal task - we don't know how to "minimize" stack.
            # everything is databand.* ...
            isolate = not self.task.task_definition.full_task_family.startswith(
                "databand.")
            traceback_str = self.settings.log.format_exception_as_str(
                exc_info=exc_info, isolate=isolate)

            self.banner.column(
                colored("TRACEBACK", color="red", attrs=["bold"]),
                traceback_str,
                raw_name=True,
            )

        self.banner.column(
            colored("ERROR MESSAGE", color="red", attrs=["bold"]),
            str(ex),
            raw_name=True,
        )

        self.banner.column(
            colored("HELP", attrs=["bold"]),
            get_help_msg(ex),
            raw_name=True,
            skip_if_empty=True,
        )
        self.banner.column(
            colored("CAUSED BY", color="red", attrs=["bold"]),
            nested_exceptions_str(ex, limit=3),
            raw_name=True,
            skip_if_empty=True,
        )
Example #2
0
 def get_callable_spec(self):
     if not self._callable_spec:
         try:
             self._callable_spec = build_callable_spec(
                 class_or_func=self.original_class_or_func
             )
         except Exception as ex:
             logger.error(
                 "Failed to create task %s: %s\n%s\n",
                 self.original_class_or_func.__name__,
                 str(ex),
                 user_side_code(context=5),
                 exc_info=show_exc_info(ex),
             )
             raise
     return self._callable_spec
Example #3
0
    def decorated(item):
        try:

            func_spec = build_task_decorator_spec(
                item=item,
                decorator_kwargs=decorator_kwargs,
                default_result=task_default_result,
            )

            # we can't create class dynamically because of python2/3
            # __name__ is not overridable

            task_cls = TaskMetaclass(
                str(item.__name__),
                (task_type, ),
                dict(
                    _conf__decorator_spec=func_spec,
                    _callable_item=None,
                    __doc__=item.__doc__,
                    __module__=item.__module__,
                    defaults=task_defaults,
                ),
            )
        except Exception as ex:
            logger.error(
                "Failed to create task %s: %s\n%s\n",
                item.__name__,
                str(ex),
                user_side_code(context=5),
                exc_info=show_exc_info(ex),
            )
            raise

        if func_spec.is_class:
            callable_item = six.add_metaclass(_DecoratedUserClassMeta)(item)
        else:
            callable_item = DbndFuncProxy(task_cls=task_cls)
        task_cls._callable_item = callable_item

        callable_item.func = item
        callable_item.task_cls = task_cls
        callable_item.task = task_cls
        callable_item.t = task_cls
        return task_cls._callable_item
Example #4
0
    def decorated(class_or_func):
        try:
            func_spec = build_task_decorator_spec(
                class_or_func=class_or_func,
                decorator_kwargs=decorator_kwargs,
                default_result=task_default_result,
            )
        except Exception as ex:
            logger.error(
                "Failed to create task %s: %s\n%s\n",
                class_or_func.__name__,
                str(ex),
                user_side_code(context=5),
                exc_info=show_exc_info(ex),
            )
            raise

        fp = TaskClsBuilder(func_spec, task_type, task_defaults)

        if func_spec.is_class:
            wrapper = six.add_metaclass(_DecoratedUserClassMeta)(class_or_func)
            fp._callable_item = wrapper

        else:

            @functools.wraps(class_or_func)
            def wrapper(*args, **kwargs):
                if in_tracking_mode():
                    with fp.tracking_context(args,
                                             kwargs) as track_result_callback:
                        return track_result_callback(fp.func(*args, **kwargs))

                return _call_handler(
                    fp.get_task_cls(),
                    call_user_code=fp.func,
                    call_args=args,
                    call_kwargs=kwargs,
                )

            wrapper.dbnd_run = fp.dbnd_run

        wrapper.__is_dbnd_task__ = True
        wrapper.func = class_or_func

        # we're using CallableLazyObjectProxy to have lazy evaluation for creating task_cls
        # this is only orchestration scenarios
        task_cls = CallableLazyObjectProxy(fp.get_task_cls)
        wrapper.task_cls = task_cls
        wrapper.task = task_cls
        wrapper.t = task_cls

        # we need lazy task_definition here, for example for dbnd_task_as_bash_operator
        wrapper.task_definition = CallableLazyObjectProxy(
            fp.get_task_definition)

        # we need to manually register the task here, since in regular flow
        # this happens in TaskMetaclass, but it's not invoked here due to lazy
        # evaluation using CallableLazyObjectProxy
        tp = TaskPassport.from_func_spec(func_spec, decorator_kwargs)

        # TODO: we can use CallableLazyObjectProxy object (task_cls) instead of task_cls_factory
        r = get_task_registry()
        r.register_task_cls_factory(
            task_cls_factory=fp.get_task_cls,
            full_task_family=tp.full_task_family,
            task_family=tp.task_family,
        )

        return wrapper
Example #5
0
def get_databand_error_message(ex, args=None, sys_exit=True):
    args = args or sys.argv
    please_report = False
    print_source = True

    if isinstance(ex, DatabandRunError):
        # we already printed all information!
        return (
            "There is an error! Your run has failed!",
            DatabandExitCodes.execution_failed,
        )

    if isinstance(ex, DatabandRuntimeError):
        exit_code = DatabandExitCodes.execution_failed
    elif isinstance(ex, DatabandConfigError):
        exit_code = DatabandExitCodes.configuration_error
    elif isinstance(ex, DatabandSystemError):
        exit_code = DatabandExitCodes.error
        please_report = True
    elif isinstance(ex, DatabandError):
        exit_code = DatabandExitCodes.error
    elif ex.__class__.__name__ == "NoCredentialsError":  # aws
        exit_code = DatabandExitCodes.configuration_error
        ex = friendly_error.config.no_credentials()
        print_source = False
    else:
        please_report = True
        exit_code = DatabandExitCodes.unknown_error

    msg = str(ex)

    extra_msg_lines = []

    nested_exceptions = nested_exceptions_str(ex)
    if nested_exceptions:
        extra_msg_lines.append("Caused by: \n%s\n" %
                               indent(nested_exceptions, "\t"))

    help_msg = get_help_msg(ex)
    if help_msg:
        extra_msg_lines.append(" Help: \n%s\n" % indent(help_msg, "\t"))

    user_frame_info_str = get_user_frame_info_str(ex)
    if user_frame_info_str and print_source:
        extra_msg_lines.append("Source: \n%s\n" %
                               indent(user_frame_info_str, "\t"))

    # if we crashed before finishing bootstrap we probably want to see the full trace, and we could have failed during config init so the verbose flag does nothing
    if (show_exc_info(ex) or config.getboolean("databand", "verbose")
            or not bootstrap._dbnd_bootstrap):
        error_info = sys.exc_info()
        extra_msg_lines.append(format_exception_as_str(error_info))

    msg = truncate_msg(msg, ERROR_MESSAGE_HEAD_SIZE, ERROR_MESSAGE_TAIL_SIZE)

    if please_report:
        extra_msg_lines.append(
            " Please report it to [email protected] or appropriate slack channel!"
        )
    msg = ("There is an error! Your run has failed with {exc_type}\n"
           "{sep}\n"
           " Command line: {command_line}\n"
           " Failure:\n{msg}\n\n"
           "{extra_msg}\n"
           "{sep}\n"
           "".format(
               sep=console_utils.error_separator(),
               command_line=subprocess.list2cmdline(args or []),
               sep_small=console_utils.error_separator_small(),
               msg=console_utils.bold(indent(msg, "\t")),
               exc_type=ex.__class__.__name__,
               extra_msg="\n ".join(extra_msg_lines),
           ))
    return msg, exit_code