~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/trace.py

Merge from bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006 by Canonical Ltd
 
1
# Copyright (C) 2005, 2006 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
51
51
# We should perhaps change back to just simply doing it here.
52
52
 
53
53
import os
 
54
import re
54
55
import sys
55
 
import re
56
56
 
57
57
from bzrlib.lazy_import import lazy_import
58
58
lazy_import(globals(), """
59
59
import errno
60
60
import logging
 
61
from cStringIO import StringIO
61
62
""")
62
63
 
63
64
import bzrlib
65
66
        zero_nine,
66
67
        )
67
68
 
 
69
lazy_import(globals(), """
 
70
from bzrlib import debug
 
71
""")
 
72
 
68
73
_file_handler = None
69
74
_stderr_handler = None
70
75
_stderr_quiet = False
71
76
_trace_file = None
72
77
_trace_depth = 0
73
78
_bzr_log_file = None
 
79
_use_apport = True
74
80
 
75
81
 
76
82
# configure convenient aliases for output routines
118
124
    _trace_file.write(out)
119
125
    # TODO: jam 20051227 Consider flushing the trace file to help debugging
120
126
    #_trace_file.flush()
121
 
debug = mutter
122
127
 
123
128
 
124
129
def _rollover_trace_maybe(trace_fname):
182
187
    errors loading plugins.
183
188
    """
184
189
    import traceback
185
 
    debug(traceback.format_exc())
 
190
    mutter(traceback.format_exc())
186
191
 
187
192
 
188
193
def enable_default_logging():
269
274
        print >>err_file, "bzr: broken pipe"
270
275
    elif isinstance(exc_object, KeyboardInterrupt):
271
276
        print >>err_file, "bzr: interrupted"
272
 
    elif getattr(exc_object, 'is_user_error', False):
 
277
    elif not getattr(exc_object, 'internal_error', True):
273
278
        report_user_error(exc_info, err_file)
274
279
    elif isinstance(exc_object, (OSError, IOError)):
275
280
        # Might be nice to catch all of these and show them as something more
276
281
        # specific, but there are too many cases at the moment.
277
282
        report_user_error(exc_info, err_file)
278
283
    else:
279
 
        report_bug(exc_info, err_file)
 
284
        return report_bug(exc_info, err_file)
280
285
 
281
286
 
282
287
# TODO: Should these be specially encoding the output?
283
288
def report_user_error(exc_info, err_file):
 
289
    """Report to err_file an error that's not an internal error.
 
290
 
 
291
    These don't get a traceback unless -Derror was given.
 
292
    """
 
293
    if 'error' in debug.debug_flags:
 
294
        report_bug(exc_info, err_file)
 
295
        return
284
296
    print >>err_file, "bzr: ERROR:", str(exc_info[1])
285
297
 
286
298
 
287
299
def report_bug(exc_info, err_file):
288
300
    """Report an exception that probably indicates a bug in bzr"""
 
301
    # local import because its only needed here, and this is not a loop.
 
302
    import tempfile
 
303
    # local import because the other functions do it too.
 
304
    import traceback
 
305
    # local import due to circular dependency
 
306
    import bzrlib.plugin
 
307
    global _use_apport
 
308
    try:
 
309
        # detect apport presence.
 
310
        import apport_utils
 
311
        import problem_report
 
312
    except ImportError:
 
313
        # not present, dont use it.
 
314
        _use_apport = False
 
315
    if not _use_apport:
 
316
        # policy disabled, or not present, use the old ui.
 
317
        return _old_report_bug(exc_info, err_file)
 
318
 
 
319
    exc_type, exc_object, exc_tb = exc_info
 
320
    err_file.write(
 
321
        "bzr: ERROR: %s.%s: %s\n" % (
 
322
        exc_type.__module__, exc_type.__name__, exc_object)
 
323
        )
 
324
    report = problem_report.ProblemReport()
 
325
    report_file, report_filename = tempfile.mkstemp(
 
326
        suffix='.txt', prefix='bzr-crash-', dir='/tmp')
 
327
    python_report_file = os.fdopen(report_file, 'w')
 
328
    try:
 
329
        report['CommandLine'] = ' '.join(sys.argv)
 
330
        # assume we are packaged as bzr.
 
331
        apport_utils.report_add_package_info(report, 'bzr')
 
332
        report['BzrPlugins'] = ' '.join(bzrlib.plugin.all_plugins())
 
333
        tb_file = StringIO()
 
334
        traceback.print_exception(exc_type, exc_object, exc_tb, file=tb_file)
 
335
        report['Traceback'] = tb_file.getvalue()
 
336
        apport_utils.report_add_os_info(report)
 
337
        report.write(python_report_file)
 
338
        # give the user a pretty output.
 
339
 
 
340
        err_file.write(
 
341
            'This is an unexpected error within bzr and we would appreciate a bug report.\n'
 
342
            '\n'
 
343
            'bzr has written a crash report file that will assist our debugging of this\n'
 
344
            'in the file %s\n'
 
345
            '\n'
 
346
            'This is a plain text file, whose contents you can check if you have privacy\n'
 
347
            'concerns. We gather the package data about bzr, your command line, plugins\n'
 
348
            'And the backtrace from within bzr. If you had a password in the URL you\n'
 
349
            'provided to bzr, you should edit that file to remove the password.\n'
 
350
            '\n'
 
351
            '** To file a bug for this please visit our bugtracker at the URL \n'
 
352
            '"https://launchpad.net/products/bzr/+filebug" and report a bug describing\n'
 
353
            'what you were attempting and attach the bzr-crash file mentioned above.\n'
 
354
            'Alternatively you can email bazaar-ng@lists.canonical.com with the same\n'
 
355
            'description and attach the bzr-crash file to the email.\n' %
 
356
                report_filename
 
357
            )
 
358
    finally:
 
359
        python_report_file.close()
 
360
    return report, report_filename
 
361
 
 
362
def _old_report_bug(exc_info, err_file):
 
363
    """Write a synopsis of an exception that is probably a bug to err_file."""
289
364
    import traceback
290
365
    exc_type, exc_object, exc_tb = exc_info
291
366
    print >>err_file, "bzr: ERROR: %s.%s: %s" % (