view tests/logexceptions.py @ 38777:83a505b5cf85

revlog: don't include trailing nullrev in revlog.revs(stop=len(revlog)) This was an odd side effect of the nullid entry that's in the index. The existing callers (mostly repair.py) seem to have handled it fine. It doesn't seem intentional, and it's pretty surprising, so let's remove that surprise. Differential Revision: https://phab.mercurial-scm.org/D4015
author Martin von Zweigbergk <martinvonz@google.com>
date Fri, 20 Jul 2018 11:17:33 -0700
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)