Ejemplo n.º 1
0
def exception_to_dict(fault, message=None):
    """Converts exceptions to a dict for use in notifications."""
    # TODO(johngarbutt) move to nova/exception.py to share with wrap_exception

    code = 500
    if hasattr(fault, "kwargs"):
        code = fault.kwargs.get('code', 500)

    # get the message from the exception that was thrown
    # if that does not exist, use the name of the exception class itself
    try:
        if not message:
            message = fault.format_message()
    # These exception handlers are broad so we don't fail to log the fault
    # just because there is an unexpected error retrieving the message
    except Exception:
        try:
            message = six.text_type(fault)
        except Exception:
            message = None
    if not message:
        message = fault.__class__.__name__
    # NOTE(dripton) The message field in the database is limited to 255 chars.
    # MySQL silently truncates overly long messages, but PostgreSQL throws an
    # error if we don't truncate it.
    u_message = utils.safe_truncate(message, 255)
    fault_dict = dict(exception=fault)
    fault_dict["message"] = u_message
    fault_dict["code"] = code
    return fault_dict
Ejemplo n.º 2
0
 def test_exception_to_dict_with_long_message_2_bytes(self):
     # Generate Russian byte string whose length is 300. This Russian UTF-8
     # character occupies 2 bytes. After truncating, the byte string length
     # should be 254.
     msg = encodeutils.safe_decode('\xd0\x92' * 150)
     truncated_msg = utils.safe_truncate(msg, 255)
     byte_message = encodeutils.safe_encode(truncated_msg)
     self.assertEqual(254, len(byte_message))
Ejemplo n.º 3
0
 def test_exception_to_dict_with_long_message_3_bytes(self):
     # Generate Chinese byte string whose length is 300. This Chinese UTF-8
     # character occupies 3 bytes. After truncating, the byte string length
     # should be 255.
     msg = u'\u8d75' * 100
     truncated_msg = utils.safe_truncate(msg, 255)
     byte_message = encodeutils.safe_encode(truncated_msg)
     self.assertEqual(255, len(byte_message))
Ejemplo n.º 4
0
 def test_exception_to_dict_with_long_message_2_bytes(self):
     # Generate Russian byte string whose length is 300. This Russian UTF-8
     # character occupies 2 bytes. After truncating, the byte string length
     # should be 254.
     msg = encodeutils.safe_decode('\xd0\x92' * 150)
     truncated_msg = utils.safe_truncate(msg, 255)
     byte_message = encodeutils.safe_encode(truncated_msg)
     self.assertEqual(254, len(byte_message))
Ejemplo n.º 5
0
 def test_exception_to_dict_with_long_message_3_bytes(self):
     # Generate Chinese byte string whose length is 300. This Chinese UTF-8
     # character occupies 3 bytes. After truncating, the byte string length
     # should be 255.
     msg = encodeutils.safe_decode('\xe8\xb5\xb5' * 100)
     truncated_msg = utils.safe_truncate(msg, 255)
     byte_message = encodeutils.safe_encode(truncated_msg)
     self.assertEqual(255, len(byte_message))
Ejemplo n.º 6
0
def exception_to_dict(fault, message=None):
    """Converts exceptions to a dict for use in notifications.

    :param fault: Exception that occurred
    :param message: Optional fault message, otherwise the message is derived
        from the fault itself.
    :returns: dict with the following items:

        - exception: the fault itself
        - message: one of (in priority order):
                   - the provided message to this method
                   - a formatted NovaException message
                   - the fault class name
        - code: integer code for the fault (defaults to 500)
    """
    # TODO(johngarbutt) move to nova/exception.py to share with wrap_exception

    code = 500
    if hasattr(fault, "kwargs"):
        code = fault.kwargs.get('code', 500)

    # get the message from the exception that was thrown
    # if that does not exist, use the name of the exception class itself
    try:
        if not message:
            message = fault.format_message()
    # These exception handlers are broad so we don't fail to log the fault
    # just because there is an unexpected error retrieving the message
    except Exception:
        # In this case either we have a NovaException which failed to format
        # the message or we have a non-nova exception which could contain
        # sensitive details. Since we're not sure, be safe and set the message
        # to the exception class name. Note that we don't guard on
        # context.is_admin here because the message is always shown in the API,
        # even to non-admin users (e.g. NoValidHost) but only the traceback
        # details are shown to users with the admin role. Checking for admin
        # context here is also not helpful because admins can perform
        # operations on a tenant user's server (migrations, reboot, etc) and
        # service startup and periodic tasks could take actions on a server
        # and those use an admin context.
        message = fault.__class__.__name__
    # NOTE(dripton) The message field in the database is limited to 255 chars.
    # MySQL silently truncates overly long messages, but PostgreSQL throws an
    # error if we don't truncate it.
    u_message = utils.safe_truncate(message, 255)
    fault_dict = dict(exception=fault)
    fault_dict["message"] = u_message
    fault_dict["code"] = code
    return fault_dict