diff --git a/src/pyappengine/__init__.py b/src/pyappengine/__init__.py index 8474c02..3a3f1a6 100644 --- a/src/pyappengine/__init__.py +++ b/src/pyappengine/__init__.py @@ -1,10 +1,12 @@ #!/usr/bin/python3 import os +import traceback from configparser import ConfigParser import logging from systemd import journal import inspect +from enum import Enum, auto from importlib import import_module from threading import Thread, Lock @@ -21,6 +23,34 @@ def is_number(s): return False +class AEErrs(Enum): + PARSE_ERROR = -32700 + INVALID_REQUEST = -32600 + METH_NOT_FOUND = -32601 + INVALID_PARAMS = -32602 + INTERNAL_ERROR = -32000 + + def __str__(self) -> str: + return ERROR_MESSAGES[self.value] + +ERROR_MESSAGES = { + AEErrs.PARSE_ERROR: """Invalid JSON was received by the server. + An error occurred on the server while parsing the JSON text.""", + AEErrs.INVALID_REQUEST: "The request sent is not a valid object.", + AEErrs.METH_NOT_FOUND: "The method does not exist / is not available.", + AEErrs.INVALID_PARAMS: "Invalid method parameter(s).", + AEErrs.INTERNAL_ERROR: "Internal error.", +} + + +class AppEngineException(Exception): + def __init__(self, error: AEErrs, mesg=None) -> None: + if mesg is None: + self.mesg = str(error) + super().__init__(self.mesg) + self.value = error.value + + class Commands(Thread): defmod = None precmd = "cmd_" @@ -81,7 +111,7 @@ class Commands(Thread): def _execute_command(self, method: str, *args, **kwargs) -> tuple: success = False - ret = "function not found" + ret = (AEErrs.INTERNAL_ERROR.value, "function not found") if hasattr(self, self.precmd + method) and inspect.ismethod( getattr(self, self.precmd + method) ): @@ -99,17 +129,27 @@ class Commands(Thread): method, self.name ) ) - ret = "param error" + ret = ( + AEErrs.INVALID_PARAMS.value, + ERROR_MESSAGES[AEErrs.INVALID_PARAMS], + ) + except AppEngineException as e: + self.log.error( + 'function "{}" of module "{}" returned an error with code {} and message "{}"'.format( + method, self.name, e.value, e.mesg + ) + ) + ret = (e.value, e.mesg) except: self.log.error( - 'function "{}" of module "{}" crashed'.format(method, self.name) + 'function "{}" of module "{}" crashed without other notif'.format( + method, self.name + ) ) - ret = "function crash" + ret = (AEErrs.INTERNAL_ERROR.value, traceback.format_exc()) self.lock.release() - if ret is None: - ret = "" - return success, ret.strip() + return success, ret def execute_command(self, module: str, method: str, *args, **kwargs): # isolate the module called