SDK-2525: Refactor errors

This commit is contained in:
Romuald Juchnowicz-Bierbasz
2019-02-13 12:53:25 +01:00
parent d78c08ae4b
commit c6d5c55dfd
10 changed files with 195 additions and 170 deletions

73
galaxy/api/errors.py Normal file
View File

@@ -0,0 +1,73 @@
from galaxy.api.jsonrpc import ApplicationError
class UnknownError(ApplicationError):
def __init__(self, data=None):
super().__init__(0, "Unknown error", data)
class InvalidCredentials(ApplicationError):
def __init__(self, data=None):
super().__init__(100, "Invalid credentials", data)
class NetworkError(ApplicationError):
def __init__(self, data=None):
super().__init__(101, "Network error", data)
class LoggedInElsewhere(ApplicationError):
def __init__(self, data=None):
super().__init__(102, "Logged in elsewhere", data)
class ProtocolError(ApplicationError):
def __init__(self, data=None):
super().__init__(103, "Protocol error", data)
class BackendNotAvailable(ApplicationError):
def __init__(self, data=None):
super().__init__(104, "Backend not available", data)
class BackendTimeout(ApplicationError):
def __init__(self, data=None):
super().__init__(105, "Backend timed out", data)
class BackendError(ApplicationError):
def __init__(self, data=None):
super().__init__(106, "Backend error", data)
class TemporaryBlocked(ApplicationError):
def __init__(self, data=None):
super().__init__(107, "Temporary blocked", data)
class Banned(ApplicationError):
def __init__(self, data=None):
super().__init__(108, "Banned", data)
class AccessDenied(ApplicationError):
def __init__(self, data=None):
super().__init__(109, "Access denied", data)
class ParentalControlBlock(ApplicationError):
def __init__(self, data=None):
super().__init__(110, "Parental control block", data)
class DeviceBlocked(ApplicationError):
def __init__(self, data=None):
super().__init__(111, "Device blocked", data)
class RegionBlocked(ApplicationError):
def __init__(self, data=None):
super().__init__(112, "Region blocked", data)
class FailedParsingManifest(ApplicationError):
def __init__(self, data=None):
super().__init__(200, "Failed parsing manifest", data)
class TooManyMessagesSent(ApplicationError):
def __init__(self, data=None):
super().__init__(300, "Too many messages sent", data)
class IncoherentLastMessage(ApplicationError):
def __init__(self, data=None):
super().__init__(400, "Different last message id on backend", data)
class MessageNotFound(ApplicationError):
def __init__(self, data=None):
super().__init__(500, "Message not found", data)

View File

@@ -26,9 +26,19 @@ class InvalidParams(JsonRpcError):
def __init__(self):
super().__init__(-32601, "Invalid params")
class Timeout(JsonRpcError):
def __init__(self):
super().__init__(-32000, "Method timed out")
class Aborted(JsonRpcError):
def __init__(self):
super().__init__(-32001, "Method aborted")
class ApplicationError(JsonRpcError):
def __init__(self, data):
super().__init__(-32003, "Custom error", data)
def __init__(self, code, message, data):
if code >= -32768 and code <= -32000:
raise ValueError("The error code in reserved range")
super().__init__(code, message, data)
Request = namedtuple("Request", ["method", "params", "id"], defaults=[{}, None])
Method = namedtuple("Method", ["callback", "internal"])
@@ -172,10 +182,13 @@ class Server():
"id": request_id,
"error": {
"code": error.code,
"message": error.message,
"data": error.data
"message": error.message
}
}
if error.data is not None:
response["error"]["data"] = error.data
self._send(response)
class NotificationClient():

View File

@@ -1,7 +1,6 @@
from dataclasses import dataclass
from typing import List
from galaxy.api.jsonrpc import ApplicationError
from galaxy.api.consts import LocalGameState, PresenceState
@dataclass
@@ -9,14 +8,6 @@ class Authentication():
user_id: str
user_name: str
class LoginError(ApplicationError):
def __init__(self, current_step, reason):
data = {
"current_step": current_step,
"reason": reason
}
super().__init__(data)
@dataclass
class LicenseInfo():
license_type: str
@@ -35,37 +26,16 @@ class Game():
dlcs: List[Dlc]
license_info: LicenseInfo
class GetGamesError(ApplicationError):
def __init__(self, reason):
data = {
"reason": reason
}
super().__init__(data)
@dataclass
class Achievement():
achievement_id: str
unlock_time: int
class GetAchievementsError(ApplicationError):
def __init__(self, reason):
data = {
"reason": reason
}
super().__init__(data)
@dataclass
class LocalGame():
game_id: str
local_game_state: LocalGameState
class GetLocalGamesError(ApplicationError):
def __init__(self, reason):
data = {
"reason": reason
}
super().__init__(data)
@dataclass
class Presence():
presence_state: PresenceState
@@ -80,47 +50,12 @@ class UserInfo():
avatar_url: str
presence: Presence
class GetFriendsError(ApplicationError):
def __init__(self, reason):
data = {
"reason": reason
}
super().__init__(data)
class GetUsersError(ApplicationError):
def __init__(self, reason):
data = {
"reason": reason
}
super().__init__(data)
class SendMessageError(ApplicationError):
def __init__(self, reason):
data = {
"reason": reason
}
super().__init__(data)
class MarkAsReadError(ApplicationError):
def __init__(self, reason):
data = {
"reason": reason
}
super().__init__(data)
@dataclass
class Room():
room_id: str
unread_message_count: int
last_message_id: str
class GetRoomsError(ApplicationError):
def __init__(self, reason):
data = {
"reason": reason
}
super().__init__(data)
@dataclass
class Message():
message_id: str
@@ -128,22 +63,8 @@ class Message():
sent_time: int
message_text: str
class GetRoomHistoryError(ApplicationError):
def __init__(self, reason):
data = {
"reason": reason
}
super().__init__(data)
@dataclass
class GameTime():
game_id: str
time_played: int
last_played_time: int
class GetGameTimeError(ApplicationError):
def __init__(self, reason):
data = {
"reason": reason
}
super().__init__(data)

View File

@@ -1,7 +1,8 @@
import asyncio
import json
from galaxy.api.types import Achievement, GetAchievementsError
from galaxy.api.types import Achievement
from galaxy.api.errors import UnknownError
def test_success(plugin, readline, write):
request = {
@@ -49,7 +50,7 @@ def test_failure(plugin, readline, write):
}
readline.side_effect = [json.dumps(request), ""]
plugin.get_unlocked_achievements.side_effect = GetAchievementsError("reason")
plugin.get_unlocked_achievements.side_effect = UnknownError()
asyncio.run(plugin.run())
plugin.get_unlocked_achievements.assert_called()
response = json.loads(write.call_args[0][0])
@@ -58,11 +59,8 @@ def test_failure(plugin, readline, write):
"jsonrpc": "2.0",
"id": "3",
"error": {
"code": -32003,
"message": "Custom error",
"data": {
"reason": "reason"
}
"code": 0,
"message": "Unknown error"
}
}

View File

@@ -1,7 +1,14 @@
import asyncio
import json
from galaxy.api.types import Authentication, LoginError
import pytest
from galaxy.api.types import Authentication
from galaxy.api.errors import (
UnknownError, InvalidCredentials, NetworkError, LoggedInElsewhere, ProtocolError,
BackendNotAvailable, BackendTimeout, BackendError, TemporaryBlocked, Banned, AccessDenied,
ParentalControlBlock, DeviceBlocked, RegionBlocked
)
def test_success(plugin, readline, write):
request = {
@@ -25,7 +32,23 @@ def test_success(plugin, readline, write):
}
}
def test_failure(plugin, readline, write):
@pytest.mark.parametrize("error,code,message", [
pytest.param(UnknownError, 0, "Unknown error", id="unknown_error"),
pytest.param(InvalidCredentials, 100, "Invalid credentials", id="invalid_credentials"),
pytest.param(NetworkError, 101, "Network error", id="network_error"),
pytest.param(LoggedInElsewhere, 102, "Logged in elsewhere", id="logged_elsewhere"),
pytest.param(ProtocolError, 103, "Protocol error", id="protocol_error"),
pytest.param(BackendNotAvailable, 104, "Backend not available", id="backend_not_available"),
pytest.param(BackendTimeout, 105, "Backend timed out", id="backend_timeout"),
pytest.param(BackendError, 106, "Backend error", id="backend_error"),
pytest.param(TemporaryBlocked, 107, "Temporary blocked", id="temporary_blocked"),
pytest.param(Banned, 108, "Banned", id="banned"),
pytest.param(AccessDenied, 109, "Access denied", id="access_denied"),
pytest.param(ParentalControlBlock, 110, "Parental control block", id="parental_control_clock"),
pytest.param(DeviceBlocked, 111, "Device blocked", id="device_blocked"),
pytest.param(RegionBlocked, 112, "Region blocked", id="region_blocked")
])
def test_failure(plugin, readline, write, error, code, message):
request = {
"jsonrpc": "2.0",
"id": "3",
@@ -33,7 +56,7 @@ def test_failure(plugin, readline, write):
}
readline.side_effect = [json.dumps(request), ""]
plugin.authenticate.side_effect = LoginError("step", "reason")
plugin.authenticate.side_effect = error()
asyncio.run(plugin.run())
plugin.authenticate.assert_called_with()
response = json.loads(write.call_args[0][0])
@@ -42,12 +65,8 @@ def test_failure(plugin, readline, write):
"jsonrpc": "2.0",
"id": "3",
"error": {
"code": -32003,
"message": "Custom error",
"data": {
"current_step": "step",
"reason": "reason"
}
"code": code,
"message": message
}
}

View File

@@ -1,9 +1,10 @@
import asyncio
import json
from galaxy.api.types import (
SendMessageError, MarkAsReadError, Room, GetRoomsError, Message, GetRoomHistoryError
)
import pytest
from galaxy.api.types import Room, Message
from galaxy.api.errors import UnknownError, TooManyMessagesSent, IncoherentLastMessage, MessageNotFound
def test_send_message_success(plugin, readline, write):
request = {
@@ -28,7 +29,11 @@ def test_send_message_success(plugin, readline, write):
"result": None
}
def test_send_message_failure(plugin, readline, write):
@pytest.mark.parametrize("error,code,message", [
pytest.param(UnknownError, 0, "Unknown error", id="unknown_error"),
pytest.param(TooManyMessagesSent, 300, "Too many messages sent", id="too_many_messages")
])
def test_send_message_failure(plugin, readline, write, error, code, message):
request = {
"jsonrpc": "2.0",
"id": "6",
@@ -40,7 +45,7 @@ def test_send_message_failure(plugin, readline, write):
}
readline.side_effect = [json.dumps(request), ""]
plugin.send_message.side_effect = SendMessageError("reason")
plugin.send_message.side_effect = error()
asyncio.run(plugin.run())
plugin.send_message.assert_called_with(room_id="15", message="Bye")
response = json.loads(write.call_args[0][0])
@@ -49,11 +54,8 @@ def test_send_message_failure(plugin, readline, write):
"jsonrpc": "2.0",
"id": "6",
"error": {
"code": -32003,
"message": "Custom error",
"data": {
"reason": "reason"
}
"code": code,
"message": message
}
}
@@ -80,7 +82,16 @@ def test_mark_as_read_success(plugin, readline, write):
"result": None
}
def test_mark_as_read_failure(plugin, readline, write):
@pytest.mark.parametrize("error,code,message", [
pytest.param(UnknownError, 0, "Unknown error", id="unknown_error"),
pytest.param(
IncoherentLastMessage,
400,
"Different last message id on backend",
id="incoherent_last_message"
)
])
def test_mark_as_read_failure(plugin, readline, write, error, code, message):
request = {
"jsonrpc": "2.0",
"id": "4",
@@ -92,7 +103,7 @@ def test_mark_as_read_failure(plugin, readline, write):
}
readline.side_effect = [json.dumps(request), ""]
plugin.mark_as_read.side_effect = MarkAsReadError("reason")
plugin.mark_as_read.side_effect = error()
asyncio.run(plugin.run())
plugin.mark_as_read.assert_called_with(room_id="18", last_message_id="7")
response = json.loads(write.call_args[0][0])
@@ -101,11 +112,8 @@ def test_mark_as_read_failure(plugin, readline, write):
"jsonrpc": "2.0",
"id": "4",
"error": {
"code": -32003,
"message": "Custom error",
"data": {
"reason": "reason"
}
"code": code,
"message": message
}
}
@@ -151,7 +159,7 @@ def test_get_rooms_failure(plugin, readline, write):
}
readline.side_effect = [json.dumps(request), ""]
plugin.get_rooms.side_effect = GetRoomsError("reason")
plugin.get_rooms.side_effect = UnknownError()
asyncio.run(plugin.run())
plugin.get_rooms.assert_called_with()
response = json.loads(write.call_args[0][0])
@@ -160,11 +168,8 @@ def test_get_rooms_failure(plugin, readline, write):
"jsonrpc": "2.0",
"id": "9",
"error": {
"code": -32003,
"message": "Custom error",
"data": {
"reason": "reason"
}
"code": 0,
"message": "Unknown error"
}
}
@@ -209,7 +214,11 @@ def test_get_room_history_from_message_success(plugin, readline, write):
}
}
def test_get_room_history_from_message_failure(plugin, readline, write):
@pytest.mark.parametrize("error,code,message", [
pytest.param(UnknownError, 0, "Unknown error", id="unknown_error"),
pytest.param(MessageNotFound, 500, "Message not found", id="message_not_found")
])
def test_get_room_history_from_message_failure(plugin, readline, write, error, code, message):
request = {
"jsonrpc": "2.0",
"id": "7",
@@ -221,7 +230,7 @@ def test_get_room_history_from_message_failure(plugin, readline, write):
}
readline.side_effect = [json.dumps(request), ""]
plugin.get_room_history_from_message.side_effect = GetRoomHistoryError("reason")
plugin.get_room_history_from_message.side_effect = error()
asyncio.run(plugin.run())
plugin.get_room_history_from_message.assert_called_with(room_id="33", message_id="88")
response = json.loads(write.call_args[0][0])
@@ -230,11 +239,8 @@ def test_get_room_history_from_message_failure(plugin, readline, write):
"jsonrpc": "2.0",
"id": "7",
"error": {
"code": -32003,
"message": "Custom error",
"data": {
"reason": "reason"
}
"code": code,
"message": message
}
}
@@ -287,7 +293,7 @@ def test_get_room_history_from_timestamp_failure(plugin, readline, write):
}
readline.side_effect = [json.dumps(request), ""]
plugin.get_room_history_from_timestamp.side_effect = GetRoomHistoryError("reason")
plugin.get_room_history_from_timestamp.side_effect = UnknownError()
asyncio.run(plugin.run())
plugin.get_room_history_from_timestamp.assert_called_with(
room_id="10",
@@ -299,11 +305,8 @@ def test_get_room_history_from_timestamp_failure(plugin, readline, write):
"jsonrpc": "2.0",
"id": "3",
"error": {
"code": -32003,
"message": "Custom error",
"data": {
"reason": "reason"
}
"code": 0,
"message": "Unknown error"
}
}

View File

@@ -1,7 +1,8 @@
import asyncio
import json
from galaxy.api.types import GameTime, GetGameTimeError
from galaxy.api.types import GameTime
from galaxy.api.errors import UnknownError
def test_success(plugin, readline, write):
request = {
@@ -46,7 +47,7 @@ def test_failure(plugin, readline, write):
}
readline.side_effect = [json.dumps(request), ""]
plugin.get_game_times.side_effect = GetGameTimeError("reason")
plugin.get_game_times.side_effect = UnknownError()
asyncio.run(plugin.run())
plugin.get_game_times.assert_called_with()
response = json.loads(write.call_args[0][0])
@@ -55,11 +56,8 @@ def test_failure(plugin, readline, write):
"jsonrpc": "2.0",
"id": "3",
"error": {
"code": -32003,
"message": "Custom error",
"data": {
"reason": "reason"
}
"code": 0,
"message": "Unknown error",
}
}

View File

@@ -1,8 +1,11 @@
import asyncio
import json
from galaxy.api.types import GetLocalGamesError, LocalGame
import pytest
from galaxy.api.types import LocalGame
from galaxy.api.consts import LocalGameState
from galaxy.api.errors import UnknownError, FailedParsingManifest
def test_success(plugin, readline, write):
request = {
@@ -38,7 +41,14 @@ def test_success(plugin, readline, write):
}
}
def test_failure(plugin, readline, write):
@pytest.mark.parametrize(
"error,code,message",
[
pytest.param(UnknownError, 0, "Unknown error", id="unknown_error"),
pytest.param(FailedParsingManifest, 200, "Failed parsing manifest", id="failed_parsing")
],
)
def test_failure(plugin, readline, write, error, code, message):
request = {
"jsonrpc": "2.0",
"id": "3",
@@ -46,7 +56,7 @@ def test_failure(plugin, readline, write):
}
readline.side_effect = [json.dumps(request), ""]
plugin.get_local_games.side_effect = GetLocalGamesError("reason")
plugin.get_local_games.side_effect = error()
asyncio.run(plugin.run())
plugin.get_local_games.assert_called_with()
response = json.loads(write.call_args[0][0])
@@ -55,11 +65,8 @@ def test_failure(plugin, readline, write):
"jsonrpc": "2.0",
"id": "3",
"error": {
"code": -32003,
"message": "Custom error",
"data": {
"reason": "reason"
}
"code": code,
"message": message
}
}

View File

@@ -1,7 +1,8 @@
import asyncio
import json
from galaxy.api.types import Game, Dlc, LicenseInfo, GetGamesError
from galaxy.api.types import Game, Dlc, LicenseInfo
from galaxy.api.errors import UnknownError
def test_success(plugin, readline, write):
request = {
@@ -73,7 +74,7 @@ def test_failure(plugin, readline, write):
}
readline.side_effect = [json.dumps(request), ""]
plugin.get_owned_games.side_effect = GetGamesError("reason")
plugin.get_owned_games.side_effect = UnknownError()
asyncio.run(plugin.run())
plugin.get_owned_games.assert_called_with()
response = json.loads(write.call_args[0][0])
@@ -82,11 +83,8 @@ def test_failure(plugin, readline, write):
"jsonrpc": "2.0",
"id": "3",
"error": {
"code": -32003,
"message": "Custom error",
"data": {
"reason": "reason"
}
"code": 0,
"message": "Unknown error"
}
}

View File

@@ -1,7 +1,8 @@
import asyncio
import json
from galaxy.api.types import UserInfo, Presence, GetFriendsError, GetUsersError
from galaxy.api.types import UserInfo, Presence
from galaxy.api.errors import UnknownError
from galaxy.api.consts import PresenceState
def test_get_friends_success(plugin, readline, write):
@@ -73,7 +74,7 @@ def test_get_friends_failure(plugin, readline, write):
}
readline.side_effect = [json.dumps(request), ""]
plugin.get_friends.side_effect = GetFriendsError("reason")
plugin.get_friends.side_effect = UnknownError()
asyncio.run(plugin.run())
plugin.get_friends.assert_called_with()
response = json.loads(write.call_args[0][0])
@@ -82,11 +83,8 @@ def test_get_friends_failure(plugin, readline, write):
"jsonrpc": "2.0",
"id": "3",
"error": {
"code": -32003,
"message": "Custom error",
"data": {
"reason": "reason"
}
"code": 0,
"message": "Unknown error",
}
}
@@ -202,7 +200,7 @@ def test_get_users_failure(plugin, readline, write):
}
readline.side_effect = [json.dumps(request), ""]
plugin.get_users.side_effect = GetUsersError("reason")
plugin.get_users.side_effect = UnknownError()
asyncio.run(plugin.run())
plugin.get_users.assert_called_with(user_id_list=["10", "11", "12"])
response = json.loads(write.call_args[0][0])
@@ -211,10 +209,7 @@ def test_get_users_failure(plugin, readline, write):
"jsonrpc": "2.0",
"id": "12",
"error": {
"code": -32003,
"message": "Custom error",
"data": {
"reason": "reason"
}
"code": 0,
"message": "Unknown error"
}
}