Esempio n. 1
0
    def _HandleAllErrors(self, exc, command_path_string, specified_arg_names):
        """Handle all errors.

    Args:
      exc: Exception, The exception that was raised.
      command_path_string: str, The '.' separated command path.
      specified_arg_names: [str], The specified arg named scrubbed for metrics.

    Raises:
      exc or a core.exceptions variant that does not produce a stack trace.
    """
        if session_capturer.SessionCapturer.capturer:
            session_capturer.SessionCapturer.capturer.CaptureException(exc)
        error_extra_info = {'error_code': getattr(exc, 'exit_code', 1)}
        if isinstance(exc, exceptions.HttpException):
            error_extra_info['http_status_code'] = exc.payload.status_code

        metrics.Commands(command_path_string,
                         config.CLOUD_SDK_VERSION,
                         specified_arg_names,
                         error=exc.__class__,
                         error_extra_info=error_extra_info)
        metrics.Error(command_path_string,
                      exc.__class__,
                      specified_arg_names,
                      error_extra_info=error_extra_info)

        exceptions.HandleError(exc, command_path_string,
                               self.__known_error_handler)
Esempio n. 2
0
    def _HandleKnownError(self,
                          command_path_string,
                          exc,
                          flag_names,
                          print_error=True):
        """For exceptions we know about, just print the error and exit.

    Args:
      command_path_string: str, The command that was run.
      exc: Exception, The exception that was raised.
      flag_names: [str], The names of the flags that were used during this
        execution.
      print_error: bool, True to print an error message, False to just exit with
        the given error code.
    """
        # If this is a known error, we may have an additional message suffix.
        message_suffix = KNOWN_ERRORS.get(type(exc), '')
        msg = '({0}) {1} {2}'.format(command_path_string,
                                     self.SafeExceptionToString(exc),
                                     message_suffix).rstrip()
        log.debug(msg, exc_info=sys.exc_info())
        if print_error:
            log.error(msg)
        metrics.Error(command_path_string, exc, flag_names)
        self._Exit(exc)
Esempio n. 3
0
    def _HandleKnownError(self,
                          exc,
                          command_path_string,
                          flag_collection,
                          print_error=True,
                          orig_exc=None):
        """Print the error and exit for exceptions of known type.

    Args:
      exc: Exception, The exception that was raised.
      command_path_string: str, The '.' separated command path.
      flag_collection: str, The flag collection name for metrics.
      print_error: bool, True to print an error message, False to just exit with
        the given error code.
      orig_exc: Exception or None, The original exception for metrics purposes
        if the exception was converted to a new type.
    """
        msg = u'({0}) {1}'.format(
            console_attr.EncodeForOutput(command_path_string),
            console_attr.EncodeForOutput(exc))
        log.debug(msg, exc_info=sys.exc_info())
        if print_error:
            log.error(msg)
        metrics_exc = orig_exc or exc
        metrics_exc_class = metrics_exc.__class__
        metrics.Error(command_path_string, metrics_exc_class, flag_collection)
        self._Exit(exc)
Esempio n. 4
0
    def _HandleAllErrors(self, exc, command_path_string, flag_collection):
        """Handle all errors.

    Args:
      exc: Exception, The exception that was raised.
      command_path_string: str, The '.' separated command path.
      flag_collection: str, The flag collection name for metrics.

    Raises:
      exc or a core.exceptions variant that does not produce a stack trace.
    """
        if isinstance(exc, exceptions.ExitCodeNoError):
            self._HandleKnownError(exc,
                                   command_path_string,
                                   flag_collection,
                                   print_error=False)
        elif isinstance(exc, core_exceptions.Error):
            self._HandleKnownError(exc,
                                   command_path_string,
                                   flag_collection,
                                   print_error=True)
        else:
            known_exc = exceptions.ConvertKnownError(exc)
            if known_exc:
                self._HandleKnownError(known_exc,
                                       command_path_string,
                                       flag_collection,
                                       print_error=True,
                                       orig_exc=exc)
            else:
                # Make sure any uncaught exceptions still make it into the log file.
                log.debug(console_attr.EncodeForOutput(exc),
                          exc_info=sys.exc_info())
                metrics.Error(exc)
                raise
Esempio n. 5
0
  def _HandleKnownError(self, exc, command_path_string, flag_collection,
                        print_error=True, orig_exc=None):
    """Print the error and exit for exceptions of known type.

    Args:
      exc: Exception, The exception that was raised.
      command_path_string: str, The '.' separated command path.
      flag_collection: str, The flag collection name for metrics.
      print_error: bool, True to print an error message, False to just exit with
        the given error code.
      orig_exc: Exception or None, The original exception for metrics purposes
        if the exception was converted to a new type.
    """
    msg = u'({0}) {1}'.format(console_attr.EncodeForOutput(command_path_string),
                              console_attr.EncodeForOutput(exc))
    log.debug(msg, exc_info=sys.exc_info())
    if print_error:
      log.error(msg)
    metrics_exc = orig_exc or exc
    metrics_exc_class = metrics_exc.__class__
    error_extra_info = {'error_code': getattr(exc, 'exit_code', 1)}
    if isinstance(exc, exceptions.HttpException):
      error_extra_info['http_status_code'] = exc.payload.status_code

    metrics.Error(command_path_string, metrics_exc_class, flag_collection,
                  error_extra_info=error_extra_info)
    if properties.VALUES.core.print_handled_tracebacks.GetBool():
      raise
    self._Exit(exc)
Esempio n. 6
0
    def _HandleAllErrors(self, exc, command_path_string, specified_arg_names):
        """Handle all errors.

    Args:
      exc: Exception, The exception that was raised.
      command_path_string: str, The '.' separated command path.
      specified_arg_names: [str], The specified arg named scrubbed for metrics.

    Raises:
      exc or a core.exceptions variant that does not produce a stack trace.
    """
        error_extra_info = {'error_code': getattr(exc, 'exit_code', 1)}

        # Returns exc.payload.status if available. Otherwise, None.
        http_status_code = getattr(getattr(exc, 'payload', None),
                                   'status_code', None)
        if http_status_code is not None:
            error_extra_info['http_status_code'] = http_status_code

        metrics.Commands(command_path_string,
                         config.CLOUD_SDK_VERSION,
                         specified_arg_names,
                         error=exc.__class__,
                         error_extra_info=error_extra_info)
        metrics.Error(command_path_string,
                      exc.__class__,
                      specified_arg_names,
                      error_extra_info=error_extra_info)

        exceptions.HandleError(exc, command_path_string,
                               self.__known_error_handler)
Esempio n. 7
0
  def _HandleKnownError(self, command_path_string, exc, print_error=True):
    """For exceptions we know about, just print the error and exit.

    Args:
      command_path_string: str, The command that was run.
      exc: Exception, The exeption that was raised.
      print_error: bool, True to print an error message, False to just exit with
        the given error code.
    """
    msg = '({0}) {1}'.format(command_path_string, str(exc))
    log.debug(msg, exc_info=sys.exc_info())
    if print_error:
      log.error(msg)
    metrics.Error(command_path_string, exc)
    self._Exit(exc)
Esempio n. 8
0
    def _HandleAllErrors(self, exc, command_path_string, specified_arg_names):
        """Handle all errors.

    Args:
      exc: Exception, The exception that was raised.
      command_path_string: str, The '.' separated command path.
      specified_arg_names: [str], The specified arg named scrubbed for metrics.

    Raises:
      exc or a core.exceptions variant that does not produce a stack trace.
    """
        if session_capturer.SessionCapturer.capturer:
            session_capturer.SessionCapturer.capturer.CaptureException(exc)
        known_exc, print_error = exceptions.ConvertKnownError(exc)
        error_extra_info = {'error_code': getattr(exc, 'exit_code', 1)}
        if isinstance(exc, exceptions.HttpException):
            error_extra_info['http_status_code'] = exc.payload.status_code

        metrics.Commands(command_path_string,
                         config.CLOUD_SDK_VERSION,
                         specified_arg_names,
                         error=exc.__class__,
                         error_extra_info=error_extra_info)
        metrics.Error(command_path_string,
                      exc.__class__,
                      specified_arg_names,
                      error_extra_info=error_extra_info)

        if known_exc:
            msg = u'({0}) {1}'.format(
                console_attr.EncodeForConsole(command_path_string),
                console_attr.EncodeForConsole(known_exc))
            log.debug(msg, exc_info=sys.exc_info())
            if print_error:
                log.error(msg)
            # Uncaught errors will be handled in gcloud_main.
            if self.__known_error_handler:
                self.__known_error_handler(exc)
            if properties.VALUES.core.print_handled_tracebacks.GetBool():
                raise
            self._Exit(known_exc)
        else:
            # Make sure any uncaught exceptions still make it into the log file.
            log.debug(console_attr.EncodeForConsole(exc),
                      exc_info=sys.exc_info())
            raise
Esempio n. 9
0
    def _HandleAllErrors(self, exc, command_path_string, specified_arg_names):
        """Handle all errors.

    Args:
      exc: Exception, The exception that was raised.
      command_path_string: str, The '.' separated command path.
      specified_arg_names: [str], The specified arg named scrubbed for metrics.

    Raises:
      exc or a core.exceptions variant that does not produce a stack trace.
    """
        if isinstance(exc, exceptions.ExitCodeNoError):
            self._HandleKnownError(exc,
                                   command_path_string,
                                   specified_arg_names,
                                   print_error=False)
        elif isinstance(exc, core_exceptions.Error):
            self._HandleKnownError(exc,
                                   command_path_string,
                                   specified_arg_names,
                                   print_error=True)
        else:
            known_exc = exceptions.ConvertKnownError(exc)
            if known_exc:
                self._HandleKnownError(known_exc,
                                       command_path_string,
                                       specified_arg_names,
                                       print_error=True,
                                       orig_exc=exc)
            else:
                # Make sure any uncaught exceptions still make it into the log file.
                log.debug(console_attr.EncodeForOutput(exc),
                          exc_info=sys.exc_info())
                metrics.Error(command_path_string,
                              exc.__class__,
                              specified_arg_names,
                              error_extra_info={'error_code': 1})
                raise
Esempio n. 10
0
  def _ReportErrorMetricsHelper(self, dotted_command_path, error,
                                error_extra_info=None):
    """Logs `Commands` and `Error` Google Analytics events for an error.

    Args:
      dotted_command_path: str, The dotted path to as much of the command as we
          can identify before an error. Example: gcloud.projects
      error: class, The class (not the instance) of the Exception for an error.
      error_extra_info: {str: json-serializable}, A json serializable dict of
        extra info that we want to log with the error. This enables us to write
        queries that can understand the keys and values in this dict.
    """
    specified_args = self.GetSpecifiedArgNames()
    metrics.Commands(
        dotted_command_path,
        config.CLOUD_SDK_VERSION,
        specified_args,
        error=error,
        error_extra_info=error_extra_info)
    metrics.Error(
        dotted_command_path,
        error,
        specified_args,
        error_extra_info=error_extra_info)
Esempio n. 11
0
  def Execute(self, args=None, call_arg_complete=True):
    """Execute the CLI tool with the given arguments.

    Args:
      args: The arguments from the command line or None to use sys.argv
      call_arg_complete: Call the _ArgComplete function if True

    Returns:
      The result of executing the command determined by the command
      implementation.
    """
    if call_arg_complete:
      self._ArgComplete()

    if not args:
      args = sys.argv[1:]

    for s in args:
      try:
        s.decode('ascii')
      except UnicodeError:
        raise exceptions.InvalidStringException(s)

    # Set the command name in case an exception happens before the command name
    # is finished parsing.
    command_path_string = self.__name
    try:
      properties.VALUES.PushInvocationValues()
      args = self.__parser.parse_args(args)
      # -h|--help|--document are dispatched by parse_args and never get here.

      # Now that we have parsed the args, reload the settings so the flags will
      # take effect.  These will use the values from the properties.
      log.SetUserOutputEnabled(None)
      log.SetVerbosity(None)

      command_path_string = '.'.join(args.command_path)
      # TODO(user): put a real version here
      metrics.Commands(command_path_string, None)

      for hook in self.__pre_run_hooks:
        hook.Run(command_path_string)

      result = args.cmd_func(cli=self, args=args)

      for hook in self.__post_run_hooks:
        hook.Run(command_path_string)

      return result

    except exceptions.ExitCodeNoError as exc:
      self._HandleKnownError(command_path_string, exc, print_error=False)
    except core_exceptions.Error as exc:
      self._HandleKnownError(command_path_string, exc, print_error=True)
    except Exception as exc:
      # Make sure any uncaught exceptions still make it into the log file.
      log.file_only_logger.debug(str(exc), exc_info=sys.exc_info())
      metrics.Error(command_path_string, exc)
      raise
    finally:
      properties.VALUES.PopInvocationValues()
      # Reset these values to their previous state now that we popped the flag
      # values.
      log.SetUserOutputEnabled(None)
      log.SetVerbosity(None)
Esempio n. 12
0
    def Execute(self, args=None, call_arg_complete=True):
        """Execute the CLI tool with the given arguments.

    Args:
      args: [str], The arguments from the command line or None to use sys.argv
      call_arg_complete: Call the _ArgComplete function if True

    Returns:
      The result of executing the command determined by the command
      implementation.

    Raises:
      ValueError: for ill-typed arguments.
    """
        if type(args) is str:
            raise ValueError(
                'Execute expects an iterable of strings, not a string.')

        if call_arg_complete:
            self._ArgComplete()

        if not args:
            args = sys.argv[1:]

        # Set the command name in case an exception happens before the command name
        # is finished parsing.
        command_path_string = self.__name

        # Look for a --configuration flag and update property state based on
        # that before proceeding to the main argparse parse step.
        named_configs.FLAG_OVERRIDE_STACK.PushFromArgs(args)
        properties.VALUES.PushInvocationValues()

        flag_names = None
        try:
            for s in args:
                try:
                    s.decode('ascii')
                except UnicodeDecodeError:
                    raise exceptions.InvalidCharacterInArgException(
                        [sys.argv[0]] + args, s)

            args = self.__parser.parse_args(args)
            flag_names = self.__parser.GetFlagCollection()
            # -h|--help|--document are dispatched by parse_args and never get here.

            # Now that we have parsed the args, reload the settings so the flags will
            # take effect.  These will use the values from the properties.
            log.SetUserOutputEnabled(None)
            log.SetVerbosity(None)

            command_path_string = '.'.join(args.command_path)
            properties.VALUES.SetInvocationValue(
                properties.VALUES.metrics.command_name, command_path_string,
                None)
            metrics.Commands(command_path_string, config.CLOUD_SDK_VERSION,
                             flag_names)

            for hook in self.__pre_run_hooks:
                hook.Run(command_path_string)

            result = args.cmd_func(cli=self, args=args)

            for hook in self.__post_run_hooks:
                hook.Run(command_path_string)

            return result

        except exceptions.ExitCodeNoError as exc:
            self._HandleKnownError(command_path_string,
                                   exc,
                                   flag_names,
                                   print_error=False)
        except core_exceptions.Error as exc:
            self._HandleKnownError(command_path_string,
                                   exc,
                                   flag_names,
                                   print_error=True)
        except Exception as exc:
            if type(exc) in KNOWN_ERRORS:
                self._HandleKnownError(command_path_string,
                                       exc,
                                       flag_names,
                                       print_error=True)
            else:
                # Make sure any uncaught exceptions still make it into the log file.
                exc_printable = self.SafeExceptionToString(exc)
                log.debug(exc_printable, exc_info=sys.exc_info())
                metrics.Error(command_path_string, exc, flag_names)
                raise
        finally:
            properties.VALUES.PopInvocationValues()
            named_configs.FLAG_OVERRIDE_STACK.Pop()
            # Reset these values to their previous state now that we popped the flag
            # values.
            log.SetUserOutputEnabled(None)
            log.SetVerbosity(None)
Esempio n. 13
0
    def Execute(self, args=None, call_arg_complete=True):
        """Execute the CLI tool with the given arguments.

    Args:
      args: [str], The arguments from the command line or None to use sys.argv
      call_arg_complete: Call the _ArgComplete function if True

    Returns:
      The result of executing the command determined by the command
      implementation.

    Raises:
      ValueError: for ill-typed arguments.
    """
        if type(args) is str:
            raise ValueError(
                'Execute expects an iterable of strings, not a string.')

        if call_arg_complete:
            self._ArgComplete()

        if not args:
            args = sys.argv[1:]

        for s in args:
            try:
                s.decode('ascii')
            except (UnicodeEncodeError, UnicodeError):
                try:
                    s_printable = s.decode('utf-8')
                except (UnicodeEncodeError, UnicodeError):
                    s_printable = repr(s)

                raise exceptions.InvalidStringException(s_printable)

        # Set the command name in case an exception happens before the command name
        # is finished parsing.
        command_path_string = self.__name

        named_configs.FLAG_OVERRIDE_STACK.AllocateFrame()
        properties.VALUES.PushInvocationValues()
        try:
            # Look for a --configuration flag and update property state based on
            # that before proceeding to the main argparse parse step.
            named_configs.FLAG_OVERRIDE_STACK.ReplaceTop(
                named_configs.AdhocConfigFlagParse(args),
                properties.PropertiesFile.Invalidate)
            args = self.__parser.parse_args(args)

            # -h|--help|--document are dispatched by parse_args and never get here.

            # In principle it's possible that the initial round of ad-hoc parsing of
            # --configuration would not agree with the later parse by argparse.  The
            # following warning is intended to be dead code, but just in case...
            if named_configs.FLAG_OVERRIDE_STACK.Peek() != args.configuration:
                log.warn('Problem parsing --configration flag.  Using named '
                         'flag value --configuration=[{0}].'.format(
                             named_configs.FLAG_OVERRIDE_STACK.Peek()))

            # Now that we have parsed the args, reload the settings so the flags will
            # take effect.  These will use the values from the properties.
            log.SetUserOutputEnabled(None)
            log.SetVerbosity(None)

            command_path_string = '.'.join(args.command_path)
            metrics.Commands(command_path_string, config.CLOUD_SDK_VERSION)

            for hook in self.__pre_run_hooks:
                hook.Run(command_path_string)

            result = args.cmd_func(cli=self, args=args)

            for hook in self.__post_run_hooks:
                hook.Run(command_path_string)

            return result

        except exceptions.ExitCodeNoError as exc:
            self._HandleKnownError(command_path_string, exc, print_error=False)
        except core_exceptions.Error as exc:
            self._HandleKnownError(command_path_string, exc, print_error=True)
        except Exception as exc:
            if type(exc) in KNOWN_ERRORS:
                self._HandleKnownError(command_path_string,
                                       exc,
                                       print_error=True)
            else:
                # Make sure any uncaught exceptions still make it into the log file.
                exc_printable = self.SafeExceptionToString(exc)
                log.file_only_logger.debug(exc_printable,
                                           exc_info=sys.exc_info())
                metrics.Error(command_path_string, exc)
                raise
        finally:
            properties.VALUES.PopInvocationValues()
            named_configs.FLAG_OVERRIDE_STACK.Pop()
            # Reset these values to their previous state now that we popped the flag
            # values.
            log.SetUserOutputEnabled(None)
            log.SetVerbosity(None)