Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #350 seperate column for errors #352

Merged
merged 2 commits into from
Jan 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 61 additions & 24 deletions dotextensions/server/handlers/basic_handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,17 +51,20 @@ def run(self, command: Command) -> Result:
except DotHttpException as exc:
logger.error(f"dothttp exception happened {exc}", exc_info=True)
result = Result(
id=command.id, result={"error_message": exc.message, "error": True}
id=command.id, result={
"error_message": exc.message, "error": True}
)
except RequestException as exc:
logger.error(f"exception from requests {exc}", exc_info=True)
result = Result(
id=command.id, result={"error_message": str(exc), "error": True}
id=command.id, result={
"error_message": str(exc), "error": True}
)
except Exception as exc:
logger.error(f"unknown error happened {exc}", exc_info=True)
result = Result(
id=command.id, result={"error_message": str(exc), "error": True}
id=command.id, result={
"error_message": str(exc), "error": True}
)
return result

Expand All @@ -71,14 +74,14 @@ def execute(self, command):
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"],
},
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)
Expand All @@ -94,7 +97,8 @@ def get_config(self, command):
target = params.get("target", "1")
nocookie = params.get("nocookie", False)
curl = params.get("curl", False)
properties = [f"{i}={j}" for i, j in params.get("properties", {}).items()]
properties = [f"{i}={j}" for i,
j in params.get("properties", {}).items()]
content = params.get("content", None)
contexts = params.get("contexts")
property_file = params.get("property-file", None)
Expand Down Expand Up @@ -123,6 +127,26 @@ def get_config(self, command):

def get_request_result(self, command, comp: RequestCompiler):
comp.load_def()
if comp.property_util.errors:
return Result(
id=command.id,
result={
"errors": [{"var": list(error.kwargs['var']), "message": str(error)} for error in comp.property_util.errors],
"response": {
"body": "",
"output_file": "",
"status": 0,
"method": "ERROR",
"url": "ERROR",
"headers": {
"Content-Type": "text/plain",
},
"error": True,
"error_message": "errors found",
"contentType": "text/plain",
},
},
)
resp = comp.get_response()
if output := comp.httpdef.output:
# body = f"Output stored in {output}"
Expand All @@ -131,7 +155,8 @@ def get_request_result(self, command, comp: RequestCompiler):
except Exception as e:
output = f"Not!. unhandled error happened : {e}"
logger.warning("unable to write because", exc_info=True)
script_result = comp.script_execution.execute_test_script(resp).as_json()
script_result = comp.script_execution.execute_test_script(
resp).as_json()
body = resp.text
response_data = {
"response": {
Expand All @@ -140,6 +165,7 @@ def get_request_result(self, command, comp: RequestCompiler):
**self._get_resp_data(resp),
},
"script_result": script_result,
"errors": [error.kwargs for error in comp.property_util.errors],
}
if resp.history:
response_data["history"] = [
Expand All @@ -153,9 +179,11 @@ def get_request_result(self, command, comp: RequestCompiler):
# redirects can add cookies
comp.httpdef.headers["cookie"] = resp.request.headers["cookie"]
try:
data.update({"http": self.get_http_from_req(comp.httpdef, comp.property_util)})
data.update({"http": self.get_http_from_req(
comp.httpdef, comp.property_util)})
except Exception as e:
logger.error("ran into error regenerating http def from parsed object")
logger.error(
"ran into error regenerating http def from parsed object")
data.update(
{"http": f"ran into error \n Exception: `{e}` message:{e.args}"}
)
Expand All @@ -175,7 +203,8 @@ def get_request_comp(self, config):

@staticmethod
def get_http_from_req(request: HttpDef, property_util: "PropertyProvider"):
http_def = MultidefHttp(import_list=[], allhttps=[request.get_http_from_req()])
http_def = MultidefHttp(import_list=[], allhttps=[
request.get_http_from_req()])
return HttpFileFormatter.format(http_def, property_util=property_util)


Expand All @@ -200,7 +229,8 @@ def load_model(self):
##
# context has varibles defined
# for resolving purpose, including them into content
self.content = self.content + CONTEXT_SEP + CONTEXT_SEP.join(self.args.contexts)
self.content = self.content + CONTEXT_SEP + \
CONTEXT_SEP.join(self.args.contexts)

def select_target(self):
for context in self.args.contexts:
Expand All @@ -219,7 +249,7 @@ def select_target(self):
self.model.import_list = model.import_list
self.load_imports()
self.content += context + "\n\n" + context

except Exception as e:
# contexts, can not always be correct syntax
# in such scenarios, don't complain, try to resolve with
Expand Down Expand Up @@ -277,19 +307,20 @@ def run(self, command: Command) -> Result:
"headers": {
"Content-Type": "text/plain",
},
"output_file":"",
"output_file": "",
"error": True,
"error_message": error_result,
"contentType": "text/plain",
}
result = {
"response": response,
"script_result": {"stdout": "", "error": "", "properties":{}, "tests":[]},
"script_result": {"stdout": "", "error": "", "properties": {}, "tests": []},
"http": "REQUEST_EXECUTION_ERROR",
"filenameExtension": ".txt",
}
result.update(response)
return Result(id=command.id, result=result)
return Result(id=command.id, result=result)


class FormatHttpFileHandler(BaseHandler):
method = "/file/format"
Expand All @@ -301,6 +332,7 @@ def run(self, command: Command) -> Result:
result = Result(id=command.id, result=command.params)
return result


class ResolveBase():

def get_resolved(self, command: Command) -> Result:
Expand All @@ -320,7 +352,7 @@ def get_resolved(self, command: Command) -> Result:
if match.start() <= pos <= match.end():
property_hovered = match.group()[2:-2].split("=")[0].strip()
break

type_dict = TypeFromPos.figure_n_get(model, pos)
if "target" not in type_dict:
command.params["target"] = 1
Expand Down Expand Up @@ -363,12 +395,14 @@ def get_resolved(self, command: Command) -> Result:
return Result(id=command.id, result=type_dict)

# return resolved string instead of model object


class GetHoveredResolvedParamFileHandler(RunHttpFileHandler, ResolveBase):
method = "/file/resolve"

def get_method(self):
return GetHoveredResolvedParamFileHandler.method

def run(self, command):
return self.get_resolved(command)

Expand All @@ -382,6 +416,7 @@ def get_method(self):
def run(self, command):
return self.get_resolved(command)


class GetNameReferencesHandler(BaseHandler):
name = "/file/names"

Expand All @@ -394,7 +429,8 @@ def run(self, command: Command) -> Result:
result = self.execute(command, filename)
except DotHttpException as ex:
result = Result(
id=command.id, result={"error_message": ex.message, "error": True}
id=command.id, result={
"error_message": ex.message, "error": True}
)
except Exception as e:
result = Result(
Expand Down Expand Up @@ -428,7 +464,8 @@ def parse_n_get(self, http_data, filename: str):
for new_model, _content in BaseModelProcessor._get_models_from_import(
model, filename
):
self.get_for_http(new_model.allhttps, imported_names, imported_urls)
self.get_for_http(new_model.allhttps,
imported_names, imported_urls)
return all_names, all_urls, imported_names, imported_urls

def get_for_http(self, allhttps, all_names, all_urls):
Expand Down
13 changes: 13 additions & 0 deletions dothttp/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ def wrapper(cls):
class exc(cls):
def __init__(self, **kwargs):
self.message = message.format(**kwargs)
self.kwargs = kwargs

return exc

Expand All @@ -17,6 +18,18 @@ def __str__(self) -> str:
return self.message


class DothttpMultiExceptions(DotHttpException):
def __init__(self, exceptions):
self.exceptions = exceptions

@property
def message(self):
return "\n".join([str(exception) for exception in self.exceptions])

def __str__(self) -> str:
return "\n".join([str(exception) for exception in self.exceptions])


@exception_wrapper(
"http def with name `{base}` not defined for http with name `{target}`"
)
Expand Down
7 changes: 6 additions & 1 deletion dothttp/parse/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ def __init__(self, args: Config):
self.content = ""
self.original_content = self.content = ""
self.property_util = PropertyProvider(self.property_file)
self.errors = []
self.load()

def load(self):
Expand Down Expand Up @@ -277,7 +278,11 @@ def load_content(self):
self.original_content = self.content = f.read()

def get_updated_content(self, content) -> str:
return self.property_util.get_updated_content(content)
try:
return self.property_util.get_updated_content(content)
except DotHttpException as e:
self.errors.append(e)
return content

def get_updated_content_object(self, content) -> str:
return self.property_util.get_updated_content(content, "obj")
Expand Down
6 changes: 5 additions & 1 deletion dothttp/parse/request_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

from ..utils.property_util import PropertyProvider, Property

from ..exceptions import DothttpUnSignedCertException
from ..exceptions import DothttpMultiExceptions, DothttpUnSignedCertException
from ..models.parse_models import Http, HttpFileType, MultidefHttp, ScriptType
from ..parse import (
APPLICATION_JSON,
Expand Down Expand Up @@ -480,6 +480,10 @@ def query_to_http(line):
class RequestCompiler(RequestBase):
def run(self):
self.load_def()
if len(self.property_util.errors) > 0:
for error in self.errors:
eprint(error)
raise DothttpMultiExceptions(self.property_util.errors)
resp = self.get_response()
self.print_req_info(resp.request)
for hist_resp in resp.history:
Expand Down
31 changes: 18 additions & 13 deletions dothttp/utils/property_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ def __init__(self, property_file=""):
self.command_line_properties = {}
self.property_file = property_file
self.is_running_system_command_enabled = False
self.errors = []

def enable_system_command(self):
self.is_running_system_command_enabled = True
Expand Down Expand Up @@ -238,19 +239,23 @@ def is_special_keyword(key):
return ret or key.startswith("$expr:")

def get_updated_content(self, content, type="str"):
content_prop_needed, props_needed = self.check_properties_for_content(
content)
for var in props_needed:
if type == "str":
value = self.resolve_property_string(var)
for text_to_replace in content_prop_needed[var].text:
content = content.replace(
"{{" + text_to_replace + "}}", str(value)
)
else:
content = self.resolve_property_object(var)
base_logger.debug(f"using `{content}` for property {var}")
return content
try:
content_prop_needed, props_needed = self.check_properties_for_content(
content)
for var in props_needed:
if type == "str":
value = self.resolve_property_string(var)
for text_to_replace in content_prop_needed[var].text:
content = content.replace(
"{{" + text_to_replace + "}}", str(value)
)
else:
content = self.resolve_property_object(var)
base_logger.debug(f"using `{content}` for property {var}")
return content
except PropertyNotFoundException as e:
self.errors.append(e)
return content

def get_updated_obj_content(self, content):
return self.get_updated_content(content, "obj")
Expand Down
Loading
Loading