From f1fc1fa5c9409977e8139b051bb892d5bf159449 Mon Sep 17 00:00:00 2001 From: Prasanth Date: Sat, 14 Dec 2024 19:38:43 +0530 Subject: [PATCH] feat: In case of user content error, response in structured way to avoid loosing history (#342) --- .../server/handlers/basic_handlers.py | 72 ++++++++++++++----- dothttp/utils/property_util.py | 3 +- poetry.lock | 60 ++++++++++++---- pyproject.toml | 6 +- 4 files changed, 106 insertions(+), 35 deletions(-) diff --git a/dotextensions/server/handlers/basic_handlers.py b/dotextensions/server/handlers/basic_handlers.py index 0190df3..78cdd21 100644 --- a/dotextensions/server/handlers/basic_handlers.py +++ b/dotextensions/server/handlers/basic_handlers.py @@ -44,23 +44,8 @@ def get_method(self): return RunHttpFileHandler.name def run(self, command: Command) -> Result: - config = self.get_config(command) try: - if config.curl: - req = self.get_curl_comp(config) - result = req.get_curl_output() - result = Result( - id=command.id, - result={ - "body": result, - "headers": { - "Content-Type": mimetypes.types_map[".sh"], - }, - }, - ) - else: - comp = self.get_request_comp(config) - result = self.get_request_result(command, comp) + result = self.execute(command) except DotHttpException as exc: logger.error(f"dothttp exception happened {exc}", exc_info=True) result = Result( @@ -76,7 +61,25 @@ def run(self, command: Command) -> Result: result = Result( id=command.id, result={"error_message": str(exc), "error": True} ) + return result + def execute(self, command): + config = self.get_config(command) + if config.curl: + req = self.get_curl_comp(config) + result = req.get_curl_output() + result = Result( + id=command.id, + result={ + "body": result, + "headers": { + "Content-Type": mimetypes.types_map[".sh"], + }, + }, + ) + else: + comp = self.get_request_comp(config) + result = self.get_request_result(command, comp) return result def get_curl_comp(self, config): @@ -253,6 +256,43 @@ def get_request_comp(self, config): def get_curl_comp(self, config): return ContentCurlCompiler(config) + def run(self, command: Command) -> Result: + """ + When handling content, if an exception is raised, the response is not in the usual format. + Instead, it returns an error message. It is better to respond with a structured response. + """ + try: + return self.execute(command) + except DotHttpException as exc: + logger.error(f"dothttp exception happened {exc}", exc_info=True) + error_result = exc.message + except RequestException as exc: + logger.error(f"exception from requests {exc}", exc_info=True) + error_result = str(exc) + except Exception as exc: + logger.error(f"unknown error happened {exc}", exc_info=True) + error_result = str(exc) + response = { + "body": error_result, + "status": 0, + "method": "REQUEST_EXECUTION_ERROR", + "url": "REQUEST_EXECUTION_ERROR", + "headers": { + "Content-Type": "text/plain", + }, + "output_file":"", + "error": True, + "error_message": error_result, + "contentType": "text/plain", + } + result = { + "response": response, + "script_result": {"stdout": "", "error": "", "properties":{}, "tests":[]}, + "http": "REQUEST_EXECUTION_ERROR", + "filenameExtension": ".txt", + } + result.update(response) + return Result(id=command.id, result=result) class FormatHttpFileHandler(BaseHandler): method = "/file/format" diff --git a/dothttp/utils/property_util.py b/dothttp/utils/property_util.py index db5e53a..716f69c 100644 --- a/dothttp/utils/property_util.py +++ b/dothttp/utils/property_util.py @@ -260,8 +260,9 @@ def validate_n_gen(prop, cache: Dict[str, Property]): if "=" in prop: key_values = prop.split("=") if len(key_values) != 2: + prop_name = key_values[0] raise HttpFileException( - message="default property should not have multiple `=`" + message=f"Property `{prop_name}` should not contain multiple `=` signs" ) key, value = key_values # strip white space for keys diff --git a/poetry.lock b/poetry.lock index ae0cb71..a8b1972 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.4 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.5 and should not be changed by hand. [[package]] name = "arpeggio" @@ -367,13 +367,13 @@ test = ["pytest (>=6)"] [[package]] name = "faker" -version = "33.0.0" +version = "33.1.0" description = "Faker is a Python package that generates fake data for you." optional = false python-versions = ">=3.8" files = [ - {file = "Faker-33.0.0-py3-none-any.whl", hash = "sha256:68e5580cb6b4226710886e595eabc13127149d6e71e9d1db65506a7fbe2c7fce"}, - {file = "faker-33.0.0.tar.gz", hash = "sha256:9b01019c1ddaf2253ca2308c0472116e993f4ad8fc9905f82fa965e0c6f932e9"}, + {file = "Faker-33.1.0-py3-none-any.whl", hash = "sha256:d30c5f0e2796b8970de68978365247657486eb0311c5abe88d0b895b68dff05d"}, + {file = "faker-33.1.0.tar.gz", hash = "sha256:1c925fc0e86a51fc46648b504078c88d0cd48da1da2595c4e712841cab43a1e4"}, ] [package.dependencies] @@ -796,13 +796,13 @@ yaml = ["ruamel.yaml"] [[package]] name = "pytest" -version = "8.3.3" +version = "8.3.4" description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.8" files = [ - {file = "pytest-8.3.3-py3-none-any.whl", hash = "sha256:a6853c7375b2663155079443d2e45de913a911a11d669df02a50814944db57b2"}, - {file = "pytest-8.3.3.tar.gz", hash = "sha256:70b98107bd648308a7952b06e6ca9a50bc660be218d53c257cc1fc94fda10181"}, + {file = "pytest-8.3.4-py3-none-any.whl", hash = "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6"}, + {file = "pytest-8.3.4.tar.gz", hash = "sha256:965370d062bce11e73868e0335abac31b4d3de0e82f4007408d242b4f8610761"}, ] [package.dependencies] @@ -1171,13 +1171,13 @@ files = [ [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] @@ -1258,13 +1258,43 @@ files = [ [[package]] name = "tomli" -version = "2.1.0" +version = "2.2.1" description = "A lil' TOML parser" optional = false python-versions = ">=3.8" files = [ - {file = "tomli-2.1.0-py3-none-any.whl", hash = "sha256:a5c57c3d1c56f5ccdf89f6523458f60ef716e210fc47c4cfb188c5ba473e0391"}, - {file = "tomli-2.1.0.tar.gz", hash = "sha256:3f646cae2aec94e17d04973e4249548320197cfabdf130015d023de4b74d8ab8"}, + {file = "tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249"}, + {file = "tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8"}, + {file = "tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff"}, + {file = "tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b"}, + {file = "tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea"}, + {file = "tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e"}, + {file = "tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98"}, + {file = "tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4"}, + {file = "tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7"}, + {file = "tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744"}, + {file = "tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec"}, + {file = "tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69"}, + {file = "tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc"}, + {file = "tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff"}, ] [[package]] @@ -1392,4 +1422,4 @@ js = [] [metadata] lock-version = "2.0" python-versions = ">=3.8,<3.14" -content-hash = "863c90c1741c895a3e983410ceff1be555fde6e143ff5f68b59649d4f7d43bb9" +content-hash = "20d7207bfe8726dfb2302b45670c0f105813879d653869d2bc28329409481792" diff --git a/pyproject.toml b/pyproject.toml index f1a18ae..abf7749 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "dothttp-req" -version = "0.0.43a28" +version = "0.0.43a29" description = "Dothttp is Simple http client for testing and development" authors = ["Prasanth "] license = "MIT" @@ -30,7 +30,7 @@ parsys-requests-unixsocket = "0.3.2" requests-aws4auth = "1.3.1" requests-ntlm = "1.3.0" restrictedpython = "7.4" -faker = "33.0.0" +faker = "33.1.0" requests-hawk = "1.2.1" msal = "1.31.1" pyyaml = "6.0.2" @@ -44,7 +44,7 @@ flask = "3.0.2" python-magic = "^0.4.27" js2py = "0.74" flask-cors = "^5.0.0" -pytest = "^8.3.3" +pytest = "^8.3.4" pytest-html = "^4.1.1" [tool.poetry.extras]