Commit 1aba2a2c authored by Pavel Spirek's avatar Pavel Spirek

Better error messages

parent d602887e
Pipeline #62 skipped
......@@ -12,7 +12,8 @@ from yangson.datamodel import InstanceIdentifier, DataModel
from yangson.instance import \
Instance, \
NonexistentInstance, \
InstanceError, \
InstanceTypeError, \
DuplicateMember, \
ArrayValue, \
ObjectValue, \
MemberName, \
......@@ -37,9 +38,8 @@ class DataLockError(Exception):
def __init__(self, msg=""):
self.msg = msg
class InstanceAlreadyPresent(InstanceError):
pass
def __str__(self):
return self.msg
class Rpc:
......@@ -132,7 +132,7 @@ class BaseDatastore:
pass
if existing_member is not None:
raise InstanceAlreadyPresent("InstanceAlreadyPresent")
raise DuplicateMember(n, recv_object_key)
# Create new member
new_member_ii = ii + [MemberName(recv_object_key)]
......@@ -155,7 +155,7 @@ class BaseDatastore:
new_n = n.update(ArrayValue(val=n.value + new_value))
self._data = new_n.top()
else:
raise ValueError("Child node can only be appended to Object or Array")
raise InstanceTypeError(n, "Child node can only be appended to Object or Array")
def put_node_rpc(self, rpc: Rpc, value: Any):
......@@ -199,7 +199,7 @@ class BaseDatastore:
ret = self._data_lock.acquire(blocking=blocking, timeout=1)
if ret:
self._lock_username = username or "(unknown)"
info("Acquired lock in datastore \"{}\" for user \"{}\"".format(self.name, username))
debug("Acquired lock in datastore \"{}\" for user \"{}\"".format(self.name, username))
else:
raise DataLockError(
"Failed to acquire lock in datastore \"{}\" for user \"{}\", already locked by \"{}\"".format(
......@@ -212,7 +212,7 @@ class BaseDatastore:
# Unlocks datastore data
def unlock_data(self):
self._data_lock.release()
info("Released lock in datastore \"{}\" for user \"{}\"".format(self.name, self._lock_username))
debug("Released lock in datastore \"{}\" for user \"{}\"".format(self.name, self._lock_username))
self._lock_username = None
# Loads the data from file
......
......@@ -39,3 +39,9 @@ class DateTimeHelpers:
dt_gmt = dt
return dt_gmt.strftime("%a, %d %b %Y %H:%M:%S GMT")
class ErrorHelpers:
@staticmethod
def epretty(e: BaseException) -> str:
return e.__class__.__name__ + ": " + str(e)
......@@ -7,13 +7,14 @@ from urllib.parse import parse_qs
from typing import Dict, List
from yangson.schema import NonexistentSchemaNode
from yangson.instance import NonexistentInstance, InstanceTypeError
from yangson.instance import NonexistentInstance, InstanceTypeError, DuplicateMember
from .config import CONFIG_GLOBAL, CONFIG_HTTP, NACM_ADMINS, API_ROOT_data, NACM_API_ROOT_data
from .helpers import CertHelpers, DateTimeHelpers
from .data import BaseDatastore, Rpc, DataLockError, NacmForbiddenError, InstanceAlreadyPresent
from .helpers import CertHelpers, DateTimeHelpers, ErrorHelpers
from .data import BaseDatastore, Rpc, DataLockError, NacmForbiddenError
QueryStrT = Dict[str, List[str]]
epretty = ErrorHelpers.epretty
def http_send_empty(prot: "H2Protocol", stream_id: int, status_code: str, status_msg: str, status_in_body: bool = True):
......@@ -91,20 +92,20 @@ def _get(prot: "H2Protocol", stream_id: int, ds: BaseDatastore, pth: str):
prot.conn.send_headers(stream_id, response_headers)
prot.conn.send_data(stream_id, response_bytes, end_stream=True)
except DataLockError as e:
warn(e.msg)
warn(epretty(e))
http_send_empty(prot, stream_id, "500", "Internal Server Error")
except NacmForbiddenError as e:
warn(e.msg)
warn(epretty(e))
http_send_empty(prot, stream_id, "403", "Forbidden")
except NonexistentSchemaNode:
warn("NonexistentSchemaNode: " + pth)
except NonexistentSchemaNode as e:
warn(epretty(e))
http_send_empty(prot, stream_id, "404", "Not Found")
except NonexistentInstance:
warn("NonexistentInstance: " + pth)
http_send_empty(prot, stream_id, "404", "Not Found")
except InstanceTypeError:
warn("InstanceTypeError: " + pth)
except NonexistentInstance as e:
warn(epretty(e))
http_send_empty(prot, stream_id, "404", "Not Found")
except InstanceTypeError as e:
warn(epretty(e))
http_send_empty(prot, stream_id, "400", "Bad Request")
finally:
ds.unlock_data()
......@@ -186,7 +187,7 @@ def get_file(prot: "H2Protocol", headers: OrderedDict, stream_id: int):
def _post(prot: "H2Protocol", data: bytes, stream_id: int, ds: BaseDatastore, pth: str):
data_str = data.decode("utf-8")
debug("prijato: " + data_str)
debug("HTTP data received: " + data_str)
url_split = pth.split("?")
url_path = url_split[0]
......@@ -195,15 +196,18 @@ def _post(prot: "H2Protocol", data: bytes, stream_id: int, ds: BaseDatastore, pt
else:
query_string = {}
info("qs = {}".format(query_string))
username = CertHelpers.get_field(prot.client_cert, "emailAddress")
rpc1 = Rpc()
rpc1.username = username
rpc1.path = url_path
json_data = json.loads(data_str)
try:
json_data = json.loads(data_str)
except ValueError as e:
error("Invalid HTTP data: " + str(e))
http_send_empty(prot, stream_id, "400", "Bad Request")
return
try:
ds.lock_data(username)
......@@ -211,20 +215,23 @@ def _post(prot: "H2Protocol", data: bytes, stream_id: int, ds: BaseDatastore, pt
ds.create_node_rpc(rpc1, json_data, insert=ins_pos)
http_send_empty(prot, stream_id, "201", "Created")
except DataLockError as e:
warn(e.msg)
warn(epretty(e))
http_send_empty(prot, stream_id, "500", "Internal Server Error")
except NacmForbiddenError as e:
warn(e.msg)
warn(epretty(e))
http_send_empty(prot, stream_id, "403", "Forbidden")
except NonexistentSchemaNode:
warn("NonexistentSchemaNode: " + pth)
except NonexistentSchemaNode as e:
warn(epretty(e))
http_send_empty(prot, stream_id, "404", "Not Found")
except NonexistentInstance:
warn("NonexistentInstance: " + pth)
except NonexistentInstance as e:
warn(epretty(e))
http_send_empty(prot, stream_id, "404", "Not Found")
except InstanceAlreadyPresent:
warn("InstanceAlreadyPresent: " + pth)
except DuplicateMember as e:
warn(epretty(e))
http_send_empty(prot, stream_id, "409", "Conflict")
except InstanceTypeError as e:
warn(epretty(e))
http_send_empty(prot, stream_id, "400", "Bad Request")
finally:
ds.unlock_data()
......@@ -256,7 +263,7 @@ def create_post_api(ds: BaseDatastore):
def _put(prot: "H2Protocol", data: bytes, stream_id: int, ds: BaseDatastore, pth: str):
data_str = data.decode("utf-8")
info("prijato: " + data_str)
debug("HTTP data received: " + data_str)
url_split = pth.split("?")
url_path = url_split[0]
......@@ -265,8 +272,6 @@ def _put(prot: "H2Protocol", data: bytes, stream_id: int, ds: BaseDatastore, pth
else:
query_string = {}
info("qs = {}".format(query_string))
username = CertHelpers.get_field(prot.client_cert, "emailAddress")
rpc1 = Rpc()
......@@ -280,16 +285,16 @@ def _put(prot: "H2Protocol", data: bytes, stream_id: int, ds: BaseDatastore, pth
ds.put_node_rpc(rpc1, json_data)
http_send_empty(prot, stream_id, "204", "No Content", False)
except DataLockError as e:
warn(e.msg)
warn(epretty(e))
http_send_empty(prot, stream_id, "500", "Internal Server Error")
except NacmForbiddenError as e:
warn(e.msg)
warn(epretty(e))
http_send_empty(prot, stream_id, "403", "Forbidden")
except NonexistentSchemaNode:
warn("NonexistentSchemaNode: " + pth)
except NonexistentSchemaNode as e:
warn(epretty(e))
http_send_empty(prot, stream_id, "404", "Not Found")
except NonexistentInstance:
warn("NonexistentInstance: " + pth)
except NonexistentInstance as e:
warn(epretty(e))
http_send_empty(prot, stream_id, "404", "Not Found")
finally:
ds.unlock_data()
......@@ -328,8 +333,6 @@ def _delete(prot: "H2Protocol", stream_id: int, ds: BaseDatastore, pth: str):
else:
query_string = {}
info("qs = {}".format(query_string))
username = CertHelpers.get_field(prot.client_cert, "emailAddress")
rpc1 = Rpc()
......@@ -341,16 +344,16 @@ def _delete(prot: "H2Protocol", stream_id: int, ds: BaseDatastore, pth: str):
ds.delete_node_rpc(rpc1)
http_send_empty(prot, stream_id, "204", "No Content", False)
except DataLockError as e:
warn(e.msg)
warn(epretty(e))
http_send_empty(prot, stream_id, "500", "Internal Server Error")
except NacmForbiddenError as e:
warn(e.msg)
warn(epretty(e))
http_send_empty(prot, stream_id, "403", "Forbidden")
except NonexistentSchemaNode:
warn("NonexistentSchemaNode: " + pth)
except NonexistentSchemaNode as e:
warn(epretty(e))
http_send_empty(prot, stream_id, "404", "Not Found")
except NonexistentInstance:
warn("NonexistentInstance: " + pth)
except NonexistentInstance as e:
warn(epretty(e))
http_send_empty(prot, stream_id, "404", "Not Found")
finally:
ds.unlock_data()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment