Update sdk/platform-tools to version 26.0.0.
[android_tools.git] / sdk / platform-tools / systrace / catapult / telemetry / third_party / web-page-replay / exception_formatter.py
blob8ceb0d4aa630ad58463a8d971bc87e07f8852eae
1 # Copyright 2015 Google Inc. All Rights Reserved.
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
15 import math
16 import os
17 import sys
18 import traceback
21 def PrintFormattedException(msg=None):
22 exception_class, exception, tb = sys.exc_info()
24 def _GetFinalFrame(tb_level):
25 while tb_level.tb_next:
26 tb_level = tb_level.tb_next
27 return tb_level.tb_frame
29 processed_tb = traceback.extract_tb(tb)
30 frame = _GetFinalFrame(tb)
31 exception_list = traceback.format_exception_only(exception_class, exception)
32 exception_string = '\n'.join(l.strip() for l in exception_list)
34 if msg:
35 print >> sys.stderr
36 print >> sys.stderr, msg
38 _PrintFormattedTrace(processed_tb, frame, exception_string)
40 def PrintFormattedFrame(frame, exception_string=None):
41 _PrintFormattedTrace(traceback.extract_stack(frame), frame, exception_string)
44 def _PrintFormattedTrace(processed_tb, frame, exception_string=None):
45 """Prints an Exception in a more useful format than the default.
46 """
47 print >> sys.stderr
49 # Format the traceback.
50 base_dir = os.path.dirname(__file__)
51 print >> sys.stderr, 'Traceback (most recent call last):'
52 for filename, line, function, text in processed_tb:
53 filename = os.path.abspath(filename)
54 if filename.startswith(base_dir):
55 filename = filename[len(base_dir)+1:]
56 print >> sys.stderr, ' %s at %s:%d' % (function, filename, line)
57 print >> sys.stderr, ' %s' % text
59 # Format the exception.
60 if exception_string:
61 print >> sys.stderr, exception_string
63 # Format the locals.
64 local_variables = [(variable, value) for variable, value in
65 frame.f_locals.iteritems() if variable != 'self']
66 print >> sys.stderr
67 print >> sys.stderr, 'Locals:'
68 if local_variables:
69 longest_variable = max(len(v) for v, _ in local_variables)
70 for variable, value in sorted(local_variables):
71 value = repr(value)
72 possibly_truncated_value = _AbbreviateMiddleOfString(value, ' ... ', 1024)
73 truncation_indication = ''
74 if len(possibly_truncated_value) != len(value):
75 truncation_indication = ' (truncated)'
76 print >> sys.stderr, ' %s: %s%s' % (variable.ljust(longest_variable + 1),
77 possibly_truncated_value,
78 truncation_indication)
79 else:
80 print >> sys.stderr, ' No locals!'
82 print >> sys.stderr
83 sys.stderr.flush()
86 def _AbbreviateMiddleOfString(target, middle, max_length):
87 if max_length < 0:
88 raise ValueError('Must provide positive max_length')
89 if len(middle) > max_length:
90 raise ValueError('middle must not be greater than max_length')
92 if len(target) <= max_length:
93 return target
94 half_length = (max_length - len(middle)) / 2.
95 return (target[:int(math.floor(half_length))] + middle +
96 target[-int(math.ceil(half_length)):])