view tests/logexceptions.py @ 40747:380a1f73830f

perf: disable revlogs clearing in `perftags` by default This aligns things with what `perfbookmarks` does. I decided to disable the revlogs clearing by default to focus on the core logic by default, ignoring side effects. If we prefer to emphasize the side effect, we can instead keep this on in `perftags` and enable it by default in `perfbookmarks`.
author Boris Feld <boris.feld@octobus.net>
date Tue, 20 Nov 2018 17:44:24 +0000
parents 8de90e006c78
children 2372284d9457
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)