Exemplo n.º 1
0
def log_and_exit(msg: str,
                 build_info: buildinfo.BuildInfo,
                 code: int = 4000,
                 exception: Optional[Exception] = None,
                 collect: bool = True):
  """Logs a user-facing error message and exits.

  This function handles all Glazier Exceptions by sequentially:
    - (Optional) Collecting logs to a zip folder on disk
    - Logging the full traceback to the debug log
    - Constructing the user-facing failure string, consisting of:
      * The message to accompany the failure
      * (Optional) The exception object, and if available, the file and line
         number of the root exception
      * The user-facing help message containing where to look for logs and
         where to go for further assistance.
    - Log the user-facing failure string
    - Exit Glazier with code 1

  Args:
    msg: The error message to accompany the failure.
    build_info: The active BuildInfo class.
    code: Error code to append to the failure message.
    exception: The exception object.
    collect: Whether to collect log files.
  """
  if collect:
    try:
      logs.Collect(os.path.join(build_info.CachePath(), r'\glazier_logs.zip'))
    except logs.LogError as e:
      logging.error('logs collection failed with %s', e)

  # Log the full traceback to _BUILD_LOG to assist in troubleshooting
  logging.debug(traceback.format_exc())

  string = f'{msg}\n\n'

  if exception:
    # Index 2 contains the traceback from the sys.exc_info() tuple
    trace = sys.exc_info()[2]
    if trace:
      # Index -1 contains the traceback object of the root exception
      trace_obj = traceback.extract_tb(trace)[-1]
      # The trace object contains the full file path, grab just the file name
      file = os.path.split(trace_obj.filename)[1]
      lineno = trace_obj.lineno

      string += f'Exception: {file}:{lineno}] {exception}\n\n'
    else:
      string += f'Exception] {exception}\n\n'

  build_log = constants.SYS_BUILD_LOG
  if winpe.check_winpe():
    build_log = constants.WINPE_BUILD_LOG

  string += (f'See {build_log} for more info. '
             f'Need help? Visit {constants.HELP_URI}#{code}')

  logging.critical(string)
  sys.exit(1)
Exemplo n.º 2
0
 def testCollectValueErr(self, wr):
     wr.side_effect = ValueError(
         'ZIP does not support timestamps before 1980')
     with Patcher() as patcher:
         patcher.fs.create_dir(constants.SYS_LOGS_PATH)
         patcher.fs.create_file(
             os.path.join(constants.SYS_LOGS_PATH, 'log1.log'))
         with self.assertRaises(logs.LogError):
             logs.Collect(r'C:\glazier.zip')
Exemplo n.º 3
0
 def testCollect(self):
     with Patcher() as patcher:
         files = [
             os.path.join(constants.SYS_LOGS_PATH, 'log1.log'),
             os.path.join(constants.SYS_LOGS_PATH, 'log2.log'),
         ]
         patcher.fs.create_dir(constants.SYS_LOGS_PATH)
         patcher.fs.create_file(files[0], contents='log1 content')
         patcher.fs.create_file(files[1], contents='log2 content')
         logs.Collect(r'C:\glazier.zip')
         with zipfile.ZipFile(r'C:\glazier.zip', 'r') as out:
             with out.open(files[1]) as f2:
                 self.assertEqual(f2.read(), b'log2 content')
Exemplo n.º 4
0
 def testCollectIOErr(self):
     with Patcher() as patcher:
         patcher.fs.create_dir(constants.SYS_LOGS_PATH)
         with self.assertRaises(logs.LogError):
             logs.Collect(constants.SYS_LOGS_PATH)