Chinaunix首页 | 论坛 | 博客
  • 博客访问: 19726439
  • 博文数量: 679
  • 博客积分: 10495
  • 博客等级: 上将
  • 技术积分: 9308
  • 用 户 组: 普通用户
  • 注册时间: 2006-07-18 10:51
文章分类

全部博文(679)

文章存档

2012年(5)

2011年(38)

2010年(86)

2009年(145)

2008年(170)

2007年(165)

2006年(89)

分类: Python/Ruby

2010-02-10 14:16:30

import os.path
import sys
import re
import traceback
    
from match import eq
from robottypes import is_str, unic
from robot.errors import DataError, TimeoutError, RemoteError

RERAISED_EXCEPTIONS = (KeyboardInterrupt, SystemExit, MemoryError)
if sys.platform.startswith('java'):
    from java.io import StringWriter, PrintWriter
    from java.lang import Throwable, OutOfMemoryError
    RERAISED_EXCEPTIONS += (OutOfMemoryError,)

_java_trace_re = re.compile('^\s+at (\w.+)')
_ignored_java_trace = ('org.python.', 'robot.running.', 'robot$py.',
                       'sun.reflect.', 'java.lang.reflect.')
_ignore_trace_until = (os.path.join('robot','running','handlers.py'), '_run_handler')
_generic_exceptions = ('AssertionError', 'AssertionFailedError', 'Exception',
                       'Error', 'RuntimeError', 'RuntimeException',
                       'DataError', 'TimeoutError', 'ExecutionFailed', 'RemoteError')


def get_error_message():
    """Returns error message of the last occurred exception.
   
    This method handles also exceptions containing unicode messages. Thus it
    MUST be used to get messages from all exceptions originating outside the
    framework.
    """
    exc_type, exc_value, exc_traceback = sys.exc_info()
    if exc_type in (KeyboardInterrupt, SystemExit):
        raise exc_value
    if _is_java_exception(exc_value):
        return _get_java_message(exc_type, exc_value)
    return _get_python_message(exc_type, exc_value)


def get_error_details():
    """Returns error message and details of the last occurred exception.
   
    Error message contains exception's type and message and details contains
    stacktrace.
   
    This method handles also exceptions containing unicode messages. Thus it
    MUST be used to get messages from all exceptions originating outside the
    framework.
    """
    exc_type, exc_value, exc_traceback = sys.exc_info()
    if exc_type in (KeyboardInterrupt, SystemExit):
        raise exc_value
    if _is_java_exception(exc_value):
        message = _get_java_message(exc_type, exc_value)
        details = _get_java_details(exc_value)
    else:
        message = _get_python_message(exc_type, exc_value)
        details = _get_python_details(exc_value, exc_traceback)
    return message, details


def _is_java_exception(exc):
    return sys.platform.startswith('java') and isinstance(exc, Throwable)

def _get_name(exc_type):
    try:
        return exc_type.__name__
    except AttributeError:
        return unic(exc_type)
   
def _msg_to_str(msg):
    if msg is None:
        return ''
    if not is_str(msg):
        return unic(msg)
    return msg


def _get_java_message(exc_type, exc_value):
    exc_name = _get_name(exc_type)
    # OOME.getMessage and even toString seem to throw NullPointerException
    if exc_type is OutOfMemoryError: 
        exc_msg = str(exc_value)
    else:
        exc_msg = exc_value.getMessage()
    return _format_message(exc_name, exc_msg, java=True)


def _get_java_details(exc_value):
    # OOME.printStackTrace seems to throw NullPointerException
    if isinstance(exc_value, OutOfMemoryError):
        return ''
    output = StringWriter()
    exc_value.printStackTrace(PrintWriter(output))
    lines = [ line for line in str(output).splitlines()
              if line and not _is_ignored_stacktrace_line(line) ]
    details = '\n'.join(lines)
    msg = _msg_to_str(exc_value.getMessage())
    if msg:
        details = details.replace(msg, '', 1)
    return details

def _is_ignored_stacktrace_line(line):
    res = _java_trace_re.match(line)
    if res is None:
        return False
    location = res.group(1)
    for entry in _ignored_java_trace:
        if location.startswith(entry):
            return True
    return False


def _get_python_message(exc_type, exc_value):
    # If exception is a "string exception" without a message exc_value is None
    if exc_value is None:
        return unic(exc_type)
    name = _get_name(exc_type)
    try:
        msg = unic(exc_value)
    except UnicodeError:   # Happens at least if exception message is unicode
        msg = unic(exc_value.args[0])
    return _format_message(name, msg)


def _get_python_details(exc_value, exc_tb):
    if isinstance(exc_value, (DataError, TimeoutError)):
        return ''
    if isinstance(exc_value, RemoteError):
        return exc_value.traceback
    tb = traceback.extract_tb(exc_tb)
    for row, (path, _, func, _) in enumerate(tb):
        if path.endswith(_ignore_trace_until[0]) and func == _ignore_trace_until[1]:
            tb = tb[row+1:]
            break
    details = 'Traceback (most recent call last):\n' \
            + ''.join(traceback.format_list(tb))
    return details.strip()


def _format_message(name, message, java=False):
    message = _msg_to_str(message)
    if java:
        message = _clean_up_java_message(message, name)
    name = name.split('.')[-1]  # Use only last part of the name
    if message == '':
        return name
    if name in _generic_exceptions:
        return message
    return '%s: %s' % (name, message)

   
def _clean_up_java_message(msg, name):
    # Remove possible stack trace from messages
    lines = msg.splitlines()
    while lines:
        if _java_trace_re.match(lines[-1]):
            lines.pop()
        else:
            break
    msg = '\n'.join(lines)
    # Remove possible exception name from the message
    tokens = msg.split(':', 1)
    if len(tokens) == 2 and tokens[0] == name:
        msg = tokens[1]
    return msg.strip()

文件路径:robotframework-2.1.2\src\robot\utils\error.py
功能:错误处理,以后再深究
阅读(37158) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~