mirror of
https://gitlab.com/qemu-project/qemu.git
synced 2025-10-30 07:57:14 +08:00
python: backport 'Change error classes to have better repr methods'
By passing all of the arguments to the base class and overriding the __str__ method when we want a different "human readable" message that isn't just printing the list of arguments, we can ensure that all custom error classes have a reasonable __repr__ implementation. In the case of ExecuteError, the pseudo-field that isn't actually correlated to an input argument can be re-imagined as a read-only property; this forces consistency in the class and makes the repr output more obviously correct. Signed-off-by: John Snow <jsnow@redhat.com> cherry picked from commit python-qemu-qmp@afdb7893f3b34212da4259b7202973f9a8cb85b3 Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
This commit is contained in:
@ -44,7 +44,10 @@ class ProtocolError(QMPError):
|
||||
|
||||
:param error_message: Human-readable string describing the error.
|
||||
"""
|
||||
def __init__(self, error_message: str):
|
||||
super().__init__(error_message)
|
||||
def __init__(self, error_message: str, *args: object):
|
||||
super().__init__(error_message, *args)
|
||||
#: Human-readable error message, without any prefix.
|
||||
self.error_message: str = error_message
|
||||
|
||||
def __str__(self) -> str:
|
||||
return self.error_message
|
||||
|
||||
@ -178,15 +178,15 @@ class DeserializationError(ProtocolError):
|
||||
:param raw: The raw `bytes` that prompted the failure.
|
||||
"""
|
||||
def __init__(self, error_message: str, raw: bytes):
|
||||
super().__init__(error_message)
|
||||
super().__init__(error_message, raw)
|
||||
#: The raw `bytes` that were not understood as JSON.
|
||||
self.raw: bytes = raw
|
||||
|
||||
def __str__(self) -> str:
|
||||
return "\n".join([
|
||||
return "\n".join((
|
||||
super().__str__(),
|
||||
f" raw bytes were: {str(self.raw)}",
|
||||
])
|
||||
))
|
||||
|
||||
|
||||
class UnexpectedTypeError(ProtocolError):
|
||||
@ -197,13 +197,13 @@ class UnexpectedTypeError(ProtocolError):
|
||||
:param value: The deserialized JSON value that wasn't an object.
|
||||
"""
|
||||
def __init__(self, error_message: str, value: object):
|
||||
super().__init__(error_message)
|
||||
super().__init__(error_message, value)
|
||||
#: The JSON value that was expected to be an object.
|
||||
self.value: object = value
|
||||
|
||||
def __str__(self) -> str:
|
||||
strval = json.dumps(self.value, indent=2)
|
||||
return "\n".join([
|
||||
return "\n".join((
|
||||
super().__str__(),
|
||||
f" json value was: {strval}",
|
||||
])
|
||||
))
|
||||
|
||||
@ -80,7 +80,7 @@ class ConnectError(QMPError):
|
||||
:param exc: The root-cause exception.
|
||||
"""
|
||||
def __init__(self, error_message: str, exc: Exception):
|
||||
super().__init__(error_message)
|
||||
super().__init__(error_message, exc)
|
||||
#: Human-readable error string
|
||||
self.error_message: str = error_message
|
||||
#: Wrapped root cause exception
|
||||
@ -108,11 +108,14 @@ class StateError(QMPError):
|
||||
"""
|
||||
def __init__(self, error_message: str,
|
||||
state: Runstate, required: Runstate):
|
||||
super().__init__(error_message)
|
||||
super().__init__(error_message, state, required)
|
||||
self.error_message = error_message
|
||||
self.state = state
|
||||
self.required = required
|
||||
|
||||
def __str__(self) -> str:
|
||||
return self.error_message
|
||||
|
||||
|
||||
F = TypeVar('F', bound=Callable[..., Any]) # pylint: disable=invalid-name
|
||||
|
||||
|
||||
@ -41,7 +41,7 @@ class _WrappedProtocolError(ProtocolError):
|
||||
:param exc: The root-cause exception.
|
||||
"""
|
||||
def __init__(self, error_message: str, exc: Exception):
|
||||
super().__init__(error_message)
|
||||
super().__init__(error_message, exc)
|
||||
self.exc = exc
|
||||
|
||||
def __str__(self) -> str:
|
||||
@ -76,15 +76,21 @@ class ExecuteError(QMPError):
|
||||
"""
|
||||
def __init__(self, error_response: ErrorResponse,
|
||||
sent: Message, received: Message):
|
||||
super().__init__(error_response.error.desc)
|
||||
super().__init__(error_response, sent, received)
|
||||
#: The sent `Message` that caused the failure
|
||||
self.sent: Message = sent
|
||||
#: The received `Message` that indicated failure
|
||||
self.received: Message = received
|
||||
#: The parsed error response
|
||||
self.error: ErrorResponse = error_response
|
||||
#: The QMP error class
|
||||
self.error_class: str = error_response.error.class_
|
||||
|
||||
@property
|
||||
def error_class(self) -> str:
|
||||
"""The QMP error class"""
|
||||
return self.error.error.class_
|
||||
|
||||
def __str__(self) -> str:
|
||||
return self.error.error.desc
|
||||
|
||||
|
||||
class ExecInterruptedError(QMPError):
|
||||
@ -110,8 +116,8 @@ class _MsgProtocolError(ProtocolError):
|
||||
:param error_message: Human-readable string describing the error.
|
||||
:param msg: The QMP `Message` that caused the error.
|
||||
"""
|
||||
def __init__(self, error_message: str, msg: Message):
|
||||
super().__init__(error_message)
|
||||
def __init__(self, error_message: str, msg: Message, *args: object):
|
||||
super().__init__(error_message, msg, *args)
|
||||
#: The received `Message` that caused the error.
|
||||
self.msg: Message = msg
|
||||
|
||||
@ -150,7 +156,7 @@ class BadReplyError(_MsgProtocolError):
|
||||
:param sent: The message that was sent that prompted the error.
|
||||
"""
|
||||
def __init__(self, error_message: str, msg: Message, sent: Message):
|
||||
super().__init__(error_message, msg)
|
||||
super().__init__(error_message, msg, sent)
|
||||
#: The sent `Message` that caused the failure
|
||||
self.sent = sent
|
||||
|
||||
|
||||
Reference in New Issue
Block a user