"""
Definition of package exceptions and JSON-RPC protocol errors.
"""
import typing
from typing import Any, Dict, Optional, Tuple, Type
from pjrpc.common.typedefs import Json
from .common import UNSET, MaybeSet
[docs]class BaseError(Exception):
"""
Base package error. All package errors are inherited from it.
"""
[docs]class IdentityError(BaseError):
"""
Raised when a batch requests/responses identifiers are not unique or missing.
"""
[docs]class DeserializationError(BaseError, ValueError):
"""
Request/response deserializatoin error.
Raised when request/response json has incorrect format.
"""
[docs]class JsonRpcError(BaseError, metaclass=JsonRpcErrorMeta):
"""
`JSON-RPC <https://www.jsonrpc.org>`_ protocol error.
For more information see `Error object <https://www.jsonrpc.org/specification#error_object>`_.
All JSON-RPC protocol errors are inherited from it.
:param code: number that indicates the error type
:param message: short description of the error
:param data: value that contains additional information about the error. May be omitted.
"""
# a number that indicates the error type that occurred
code: int = None # type: ignore[assignment]
# a string providing a short description of the error.
# the message SHOULD be limited to a concise single sentence.
message: str = None # type: ignore[assignment]
[docs] @classmethod
def from_json(cls, json_data: 'Json') -> 'JsonRpcError':
"""
Deserializes an error from json data. If data format is not correct :py:class:`ValueError` is raised.
:param json_data: json data the error to be deserialized from
:returns: deserialized error
:raises: :py:class:`pjrpc.common.exceptions.DeserializationError` if format is incorrect
"""
try:
if not isinstance(json_data, dict):
raise DeserializationError("data must be of type dict")
code = json_data['code']
if not isinstance(code, int):
raise DeserializationError("field 'code' must be of type integer")
message = json_data['message']
if not isinstance(message, str):
raise DeserializationError("field 'message' must be of type string")
error_class = cls.get_error_cls(code, cls)
return error_class(code, message, json_data.get('data', UNSET))
except KeyError as e:
raise DeserializationError(f"required field {e} not found") from e
@classmethod
def get_error_cls(cls, code: int, default: Type['JsonRpcError']) -> Type['JsonRpcError']:
return type(cls).__errors_mapping__.get(code, default)
def __init__(self, code: Optional[int] = None, message: Optional[str] = None, data: MaybeSet[Any] = UNSET):
assert code or self.code, "code is not provided"
assert message or self.message, "message is not provided"
self.code = code or self.code
self.message = message or self.message
self.data = data
super().__init__(code, message)
def __str__(self) -> str:
return "({code}) {message}".format(code=self.code, message=self.message)
def __repr__(self) -> str:
return "{class_name}(code={code}, message={message}, data={data})".format(
class_name=self.__class__.__name__, code=repr(self.code), message=repr(self.message), data=repr(self.data),
)
def __eq__(self, other: Any) -> bool:
if not isinstance(other, JsonRpcError):
return NotImplemented
return (self.code, self.message, self.data) == (other.code, other.message, other.data)
[docs] def to_json(self) -> 'Json':
"""
Serializes the error to a dict.
:returns: serialized error
"""
json: Dict[str, Any] = {
'code': self.code,
'message': self.message,
}
if self.data is not UNSET:
json.update(data=self.data)
return json
[docs]class ClientError(JsonRpcError):
"""
Raised when a client sent an incorrect request.
"""
[docs]class ParseError(ClientError):
"""
Invalid JSON was received by the server.
An error occurred on the server while parsing the JSON text.
"""
code = -32700
message = 'Parse error'
[docs]class InvalidRequestError(ClientError):
"""
The JSON sent is not a valid request object.
"""
code = -32600
message = 'Invalid Request'
[docs]class MethodNotFoundError(ClientError):
"""
The method does not exist / is not available.
"""
code = -32601
message = 'Method not found'
[docs]class InvalidParamsError(ClientError):
"""
Invalid method parameter(s).
"""
code = -32602
message = 'Invalid params'
[docs]class InternalError(JsonRpcError):
"""
Internal JSON-RPC error.
"""
code = -32603
message = 'Internal error'
[docs]class ServerError(JsonRpcError):
"""
Reserved for implementation-defined server-errors.
Codes from -32000 to -32099.
"""
code = -32000
message = 'Server error'