[UPD] Exception handling
This commit is contained in:
@@ -6,7 +6,11 @@ from app.api.cruds.base import create, read, update, delete, read_all
|
|||||||
from app.schema.library import Library
|
from app.schema.library import Library
|
||||||
from ..db.config.config import get_engine_configuration
|
from ..db.config.config import get_engine_configuration
|
||||||
|
|
||||||
|
from sqlalchemy.exc import NoResultFound
|
||||||
|
|
||||||
from .exceptions import LibraryCreationException
|
from .exceptions import LibraryCreationException
|
||||||
|
from .exceptions import LibraryReadException
|
||||||
|
from .exceptions import LibraryUpdateException
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
logging.basicConfig(level=logging.DEBUG)
|
logging.basicConfig(level=logging.DEBUG)
|
||||||
@@ -68,6 +72,7 @@ class LibraryController:
|
|||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
#CRUDS
|
||||||
def create(self, library:Library):
|
def create(self, library:Library):
|
||||||
try:
|
try:
|
||||||
self._library = create(self.session, library)
|
self._library = create(self.session, library)
|
||||||
@@ -76,20 +81,35 @@ class LibraryController:
|
|||||||
"Cannot create library",
|
"Cannot create library",
|
||||||
f"{e.orig}",
|
f"{e.orig}",
|
||||||
"library",
|
"library",
|
||||||
str(library),
|
str(library)
|
||||||
400
|
|
||||||
)
|
)
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def read(self, _id):
|
def read(self, _id):
|
||||||
self._library = read(self.session, _id, Library)
|
try:
|
||||||
|
self._library = read(self.session, _id, Library)
|
||||||
|
except NoResultFound as e:
|
||||||
|
raise LibraryReadException(
|
||||||
|
f"Cannot read Library with id {_id}",
|
||||||
|
f"{e}",
|
||||||
|
"library",
|
||||||
|
_id
|
||||||
|
)
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def read_all(self):
|
def read_all(self):
|
||||||
self._libraries = read_all(self.session, Library)
|
self._libraries = read_all(self.session, Library)
|
||||||
|
|
||||||
def update(self):
|
def update(self):
|
||||||
self.session.commit()
|
try:
|
||||||
|
self.session.commit()
|
||||||
|
except IntegrityError as e:
|
||||||
|
raise LibraryUpdateException(
|
||||||
|
f"Cannot update Library",
|
||||||
|
f"{e}",
|
||||||
|
"library",
|
||||||
|
None
|
||||||
|
)
|
||||||
|
|
||||||
def delete(self):
|
def delete(self):
|
||||||
delete(self.session, self.data)
|
delete(self.session, self.data)
|
||||||
|
|||||||
@@ -1,2 +1,5 @@
|
|||||||
from .base import LibraryExceptionBase
|
from .base import LibraryExceptionBase
|
||||||
|
from .exc_01000X_data import LibraryDataExection
|
||||||
from .exc_01001X_create import LibraryCreationException
|
from .exc_01001X_create import LibraryCreationException
|
||||||
|
from .exc_01002X_read import LibraryReadException
|
||||||
|
from .exc_01003X_update import LibraryUpdateException
|
||||||
@@ -1,18 +1,26 @@
|
|||||||
class LibraryExceptionBase(Exception):
|
class LibraryExceptionBase(Exception):
|
||||||
def __init__(self, code, error):
|
def __init__(self, name, error, object_name, data, *, status_code=400):
|
||||||
self.code = code
|
self.code = "000000"
|
||||||
|
self.name = name
|
||||||
self.error = error
|
self.error = error
|
||||||
|
self.object = object_name
|
||||||
|
self.data = data
|
||||||
|
self.status_code = status_code
|
||||||
|
|
||||||
def to_dict(self):
|
def to_dict(self):
|
||||||
return {
|
return {
|
||||||
"status": "error",
|
"status": "error",
|
||||||
|
"name": self.name,
|
||||||
"code": self.code,
|
"code": self.code,
|
||||||
"error": self.error,
|
"error": self.error,
|
||||||
"status_code": 400
|
"object": self.object,
|
||||||
|
"data": self.data,
|
||||||
|
"status_code": self.status_code
|
||||||
}
|
}
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"ERROR {self.code}: {self.error}"
|
return f"ERROR {self.code}: {self.error}"
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f"LibraryExceptionBase(code={self.code!r}, error={self.error!r})"
|
return f"{self.__class__}(code={self.code!r}, error={self.error!r}), " \
|
||||||
|
f"object={self.object!r}, data={self.data!r}, status_code={self._status_code})"
|
||||||
7
app/controller/exceptions/exc_01000X_data.py
Normal file
7
app/controller/exceptions/exc_01000X_data.py
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
from .base import LibraryExceptionBase
|
||||||
|
|
||||||
|
#010010
|
||||||
|
class LibraryDataExection(LibraryExceptionBase):
|
||||||
|
def __init__(self, name, error, object_name, data, *, status_code=400):
|
||||||
|
self.code = "010000"
|
||||||
|
super().__init__(name, error, object_name, data, status_code=status_code)
|
||||||
@@ -2,25 +2,6 @@ from .base import LibraryExceptionBase
|
|||||||
|
|
||||||
#010010
|
#010010
|
||||||
class LibraryCreationException(LibraryExceptionBase):
|
class LibraryCreationException(LibraryExceptionBase):
|
||||||
def __init__(self, name, error, object, data, status_code=400):
|
def __init__(self, name, error, object_name, data, *, status_code=400):
|
||||||
self.code = "010010"
|
self.code = "010010"
|
||||||
self.name = name
|
super().__init__(name, error, object_name, data, status_code=status_code)
|
||||||
self.error = error
|
|
||||||
self.object = object
|
|
||||||
self.data = data
|
|
||||||
self.status_code = status_code
|
|
||||||
|
|
||||||
def to_dict(self):
|
|
||||||
return {
|
|
||||||
"status": "error",
|
|
||||||
"name": self.name,
|
|
||||||
"code": self.code,
|
|
||||||
"error": self.error,
|
|
||||||
"object": self.object,
|
|
||||||
"data": self.data,
|
|
||||||
"status_code": self.status_code
|
|
||||||
}
|
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
return f"LibraryCreationException(code={self.code!r}, error={self.error!r}), " \
|
|
||||||
f"object={self.object!r}, data={self.data!r}"
|
|
||||||
7
app/controller/exceptions/exc_01002X_read.py
Normal file
7
app/controller/exceptions/exc_01002X_read.py
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
from .base import LibraryExceptionBase
|
||||||
|
|
||||||
|
#010030
|
||||||
|
class LibraryReadException(LibraryExceptionBase):
|
||||||
|
def __init__(self, name, error, object_name, data, status_code=404):
|
||||||
|
super().__init__(name, error, object_name, data, status_code=status_code)
|
||||||
|
self.code = "010030"
|
||||||
7
app/controller/exceptions/exc_01003X_update.py
Normal file
7
app/controller/exceptions/exc_01003X_update.py
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
from .base import LibraryExceptionBase
|
||||||
|
|
||||||
|
#010020
|
||||||
|
class LibraryUpdateException(LibraryExceptionBase):
|
||||||
|
def __init__(self, name, error, object_name, data, status_code=404):
|
||||||
|
super().__init__(name, error, object_name, data, status_code=status_code)
|
||||||
|
self.code = "010020"
|
||||||
1
app/controller/functions/__init__.py
Normal file
1
app/controller/functions/__init__.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
from .update_item_key import update_item_key
|
||||||
21
app/controller/functions/update_item_key.py
Normal file
21
app/controller/functions/update_item_key.py
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
from ..exceptions import LibraryDataExection
|
||||||
|
from ...schema.library import Base
|
||||||
|
|
||||||
|
def update_item_key(obj:Base, key, value):
|
||||||
|
if key == "id":
|
||||||
|
raise LibraryDataExection(
|
||||||
|
"id is not updatable",
|
||||||
|
"The key ID is not Updatable",
|
||||||
|
obj.__class__,
|
||||||
|
{key: value}
|
||||||
|
)
|
||||||
|
try:
|
||||||
|
obj.__getattribute__(key)
|
||||||
|
except AttributeError:
|
||||||
|
raise LibraryDataExection(
|
||||||
|
f"{key} not in {obj.__class__}",
|
||||||
|
f"The key {key} is not in {obj.__class__}",
|
||||||
|
obj.__class__,
|
||||||
|
{key: value}
|
||||||
|
)
|
||||||
|
obj.__setattr__(key, value)
|
||||||
@@ -16,6 +16,7 @@ def handle_exception(e):
|
|||||||
"status_code": e.status_code,
|
"status_code": e.status_code,
|
||||||
"name": e.name,
|
"name": e.name,
|
||||||
"error": e.error,
|
"error": e.error,
|
||||||
|
"data": e.data
|
||||||
})
|
})
|
||||||
response.content_type = "application/json"
|
response.content_type = "application/json"
|
||||||
response.status_code = e.status_code
|
response.status_code = e.status_code
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
from flask import request
|
from flask import request
|
||||||
from sqlalchemy.exc import IntegrityError
|
|
||||||
|
|
||||||
from .blueprint import api_library
|
from .blueprint import api_library
|
||||||
|
|
||||||
|
|||||||
@@ -12,11 +12,7 @@ logger = logging.getLogger(__name__)
|
|||||||
@api_library.route("/<_id>", methods=["DELETE"])
|
@api_library.route("/<_id>", methods=["DELETE"])
|
||||||
def delete_library(_id):
|
def delete_library(_id):
|
||||||
|
|
||||||
try: # TODO: function
|
controller = LibraryController(_id)
|
||||||
controller = LibraryController(_id)
|
|
||||||
except NoResultFound as e:
|
|
||||||
logger.debug({e})
|
|
||||||
return { "status": "error", "error": "Library not found" }, 404
|
|
||||||
|
|
||||||
controller.delete()
|
controller.delete()
|
||||||
|
|
||||||
|
|||||||
@@ -17,11 +17,5 @@ def read_libraries():
|
|||||||
|
|
||||||
@api_library.route("/<_id>", methods=["GET"])
|
@api_library.route("/<_id>", methods=["GET"])
|
||||||
def read_library(_id):
|
def read_library(_id):
|
||||||
try:
|
library = LibraryController(_id)
|
||||||
library = LibraryController(_id)
|
|
||||||
except NoResultFound as e:
|
|
||||||
logger.debug(f"No result found for Library wid id {_id}")
|
|
||||||
logger.debug(f"Error {e}")
|
|
||||||
logger.debug(f"Error {dir(e)}")
|
|
||||||
return { "status": "error", "result": "Library not found"}, 404
|
|
||||||
return { "status": "ok", "result": library.data.to_dict() }, 200
|
return { "status": "ok", "result": library.data.to_dict() }, 200
|
||||||
|
|||||||
@@ -4,47 +4,24 @@ from sqlalchemy.exc import IntegrityError, NoResultFound
|
|||||||
from .blueprint import api_library
|
from .blueprint import api_library
|
||||||
|
|
||||||
from ....controller import LibraryController
|
from ....controller import LibraryController
|
||||||
|
from ....controller.functions import update_item_key
|
||||||
from ....schema.library.library import Library
|
from ....schema.library.library import Library
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
def update_library_item(library:Library, key, value):
|
|
||||||
if key == "id":
|
|
||||||
raise AttributeError("id is not updatable")
|
|
||||||
try:
|
|
||||||
library.__getattribute__(key)
|
|
||||||
except AttributeError:
|
|
||||||
raise AttributeError(f"{key} not in library")
|
|
||||||
library.__setattr__(key, value)
|
|
||||||
|
|
||||||
@api_library.route("/<_id>", methods=["PATCH"])
|
@api_library.route("/<_id>", methods=["PATCH"])
|
||||||
def update_library(_id):
|
def update_library(_id):
|
||||||
try:
|
|
||||||
data:dict = request.json
|
|
||||||
logger.debug(f"data: {data}")
|
|
||||||
except Exception as e:
|
|
||||||
logger.debug(f"{e}")
|
|
||||||
return { "status": "error", "error": "JSON Required" }, 415
|
|
||||||
|
|
||||||
try: # TODO: function
|
data:dict = request.json
|
||||||
controller = LibraryController(_id)
|
controller = LibraryController(_id)
|
||||||
except NoResultFound as e:
|
|
||||||
logger.debug({e})
|
|
||||||
return { "status": "error", "error": "Library not found" }, 404
|
|
||||||
|
|
||||||
library = controller.data
|
library = controller.data
|
||||||
for key, value in data.items():
|
for key, value in data.items():
|
||||||
try:
|
update_item_key(library, key, value)
|
||||||
update_library_item(library, key, value)
|
|
||||||
except AttributeError as e:
|
|
||||||
logger.debug(f"Error updating {e}")
|
|
||||||
return { "status": "error", "error": e.name }
|
|
||||||
|
|
||||||
try:
|
controller.update()
|
||||||
controller.update()
|
|
||||||
except IntegrityError as e:
|
return { "status": "ok", "result": controller.data.to_dict() }, 200
|
||||||
logger.debug(f"DB Error Creating {e}")
|
|
||||||
return { "status": "error", "error": f"{e.orig}" }, 400
|
|
||||||
else:
|
|
||||||
return { "status": "ok", "result": controller.data.to_dict() }, 200
|
|
||||||
@@ -3,5 +3,5 @@ query = sqlite:///test.db
|
|||||||
|
|
||||||
[App]
|
[App]
|
||||||
port = 15012
|
port = 15012
|
||||||
debug = False
|
debug = True
|
||||||
|
|
||||||
|
|||||||
@@ -7,11 +7,13 @@ from app.api.actions import install
|
|||||||
from app.schema.library import Library, Tag, Book, BookTag, Path, Env
|
from app.schema.library import Library, Tag, Book, BookTag, Path, Env
|
||||||
from app.controller import LibraryController
|
from app.controller import LibraryController
|
||||||
|
|
||||||
|
from app.controller.exceptions import LibraryReadException
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
logging.basicConfig(level=logging.DEBUG)
|
logging.basicConfig(level=logging.DEBUG)
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
class TestDB(unittest.TestCase):
|
class TestController(unittest.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
os.environ["DEV_URIA_BIBLIOGAME_CONFIG_DB"] = "sqlite:///"
|
os.environ["DEV_URIA_BIBLIOGAME_CONFIG_DB"] = "sqlite:///"
|
||||||
@@ -141,7 +143,7 @@ class TestDB(unittest.TestCase):
|
|||||||
library = LibraryController(1, engine=self.engine)
|
library = LibraryController(1, engine=self.engine)
|
||||||
library.delete()
|
library.delete()
|
||||||
|
|
||||||
self.assertRaises(NoResultFound, LibraryController, 1, engine=self.engine)
|
self.assertRaises(LibraryReadException, LibraryController, 1, engine=self.engine)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
Reference in New Issue
Block a user