view tests/logexceptions.py @ 44195:51c86c6167c1

pathutil: mark parent directories as audited as we go Before 0b7ce0b16d8a (pathauditor: change parts verification order to be root first, 2016-02-11), we used to validate child directories before parents. It was then important to only mark the child audited only after we had audited its parent (ancestors). I'm pretty sure we don't need to do that any more, now that we audit parents before children. Differential Revision: https://phab.mercurial-scm.org/D8002
author Martin von Zweigbergk <martinvonz@google.com>
date Fri, 24 Jan 2020 17:25:40 -0800
parents 2372284d9457
children d4ba4d51f85f
line wrap: on
line source

# logexceptions.py - Write files containing info about Mercurial exceptions
#
# Copyright 2017 Matt Mackall <mpm@selenic.com>
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.

from __future__ import absolute_import

import inspect
import os
import sys
import traceback
import uuid

from mercurial import (
    dispatch,
    extensions,
)


def handleexception(orig, ui):
    res = orig(ui)

    if not ui.environ.get(b'HGEXCEPTIONSDIR'):
        return res

    dest = os.path.join(
        ui.environ[b'HGEXCEPTIONSDIR'], str(uuid.uuid4()).encode('ascii')
    )

    exc_type, exc_value, exc_tb = sys.exc_info()

    stack = []
    tb = exc_tb
    while tb:
        stack.append(tb)
        tb = tb.tb_next
    stack.reverse()

    hgframe = 'unknown'
    hgline = 'unknown'

    # Find the first Mercurial frame in the stack.
    for tb in stack:
        mod = inspect.getmodule(tb)
        if not mod.__name__.startswith(('hg', 'mercurial')):
            continue

        frame = tb.tb_frame

        try:
            with open(inspect.getsourcefile(tb), 'r') as fh:
                hgline = fh.readlines()[frame.f_lineno - 1].strip()
        except (IndexError, OSError):
            pass

        hgframe = '%s:%d' % (frame.f_code.co_filename, frame.f_lineno)
        break

    primary = traceback.extract_tb(exc_tb)[-1]
    primaryframe = '%s:%d' % (primary.filename, primary.lineno)

    with open(dest, 'wb') as fh:
        parts = [
            str(exc_value),
            primaryframe,
            hgframe,
            hgline,
            ui.environ[b'TESTNAME'].decode('utf-8', 'replace'),
        ]
        fh.write(b'\0'.join(p.encode('utf-8', 'replace') for p in parts))


def extsetup(ui):
    extensions.wrapfunction(dispatch, 'handlecommandexception', handleexception)