Skip to content

Commit

Permalink
chore: don't log errors multiple times (DEV-3195) (#769)
Browse files Browse the repository at this point in the history
  • Loading branch information
jnussbaum committed Jan 30, 2024
1 parent 5159b8d commit 0025784
Show file tree
Hide file tree
Showing 7 changed files with 18 additions and 33 deletions.
2 changes: 1 addition & 1 deletion src/dsp_tools/cli/entry_point.py
Expand Up @@ -65,7 +65,7 @@ def run(args: list[str]) -> None:
)
success = call_requested_action(parsed_arguments)
except BaseError as err:
logger.exception(err)
logger.exception("The process was terminated because of an Error:")
print("\nThe process was terminated because of an Error:")
print(err.message)
sys.exit(1)
Expand Down
1 change: 0 additions & 1 deletion src/dsp_tools/commands/ingest_xmlupload/upload_xml.py
Expand Up @@ -56,7 +56,6 @@ def ingest_xmlupload(
logger.info(ok)
else:
err_msg = ingest_info.execute_error_protocol()
logger.error(err_msg)
raise InputError(err_msg)

xmlupload(
Expand Down
9 changes: 3 additions & 6 deletions src/dsp_tools/commands/xmlupload/ark2iri.py
Expand Up @@ -40,17 +40,14 @@ def convert_ark_v0_to_resource_iri(ark: str) -> str:

# get the salsah resource ID from the ARK and convert it to a UUID version 5 (base64 encoded)
if ark.count("-") != 2:
logger.error(f"while converting ARK '{ark}'. The ARK seems to be invalid")
raise BaseError(f"while converting ARK '{ark}'. The ARK seems to be invalid")
raise BaseError(f"Error while converting ARK '{ark}'. The ARK seems to be invalid")
project_id, resource_id, _ = ark.split("-")
_, project_id = project_id.rsplit("/", 1)
project_id = project_id.upper()
if not regex.match("^[0-9a-fA-F]{4}$", project_id):
logger.error(f"while converting ARK '{ark}'. Invalid project shortcode '{project_id}'")
raise BaseError(f"while converting ARK '{ark}'. Invalid project shortcode '{project_id}'")
raise BaseError(f"Error while converting ARK '{ark}'. Invalid project shortcode '{project_id}'")
if not regex.match("^[0-9A-Za-z]+$", resource_id):
logger.error(f"while converting ARK '{ark}'. Invalid Salsah ID '{resource_id}'")
raise BaseError(f"while converting ARK '{ark}'. Invalid Salsah ID '{resource_id}'")
raise BaseError(f"Error while converting ARK '{ark}'. Invalid Salsah ID '{resource_id}'")

# make a UUID v5 from the namespace created above (which is a UUID itself) and the resource ID
# and encode it to base64
Expand Down
5 changes: 2 additions & 3 deletions src/dsp_tools/commands/xmlupload/project_client.py
Expand Up @@ -96,10 +96,9 @@ def _get_ontologies_from_server(con: Connection, project_iri: str) -> list[str]:
case dict():
return [body["@id"]]
case _:
raise BaseError(f"Unexpected response from server: {body}")
raise BaseError("Unexpected response from server")
except BaseError as e:
logger.exception(e)
raise BaseError(f"Ontologies for project {project_iri} could not be retrieved from the DSP server") from None
raise BaseError(f"Ontologies for project {project_iri} could not be retrieved from the DSP server") from e


def _extract_name_from_onto_iri(iri: str) -> str:
Expand Down
27 changes: 9 additions & 18 deletions src/dsp_tools/commands/xmlupload/xmlupload.py
Expand Up @@ -198,14 +198,13 @@ def _upload(
)
if nonapplied_stash:
msg = "Some stashed resptrs or XML texts could not be reapplied to their resources on the DSP server."
logger.error(msg)
raise BaseError(msg)
except BaseException as err: # noqa: BLE001 (blind-except)
# The forseeable errors are already handled by the variables
# failed_uploads, nonapplied_xml_texts, and nonapplied_resptr_props.
# Here we catch the unforseeable exceptions, hence BaseException (=the base class of all exceptions)
_handle_upload_error(
err=err,
err_msg=str(err),
iri_resolver=iri_resolver,
failed_uploads=failed_uploads,
stash=stash,
Expand Down Expand Up @@ -367,19 +366,11 @@ def _create_resource(
) -> tuple[str, str] | None:
try:
return resource_create_client.create_resource(resource, bitstream_information)
except BaseError as err:
err_msg = err.message
print(f"{datetime.now()}: WARNING: Unable to create resource '{resource.label}' ({resource.res_id}): {err_msg}")
log_msg = (
f"Unable to create resource '{resource.label}' ({resource.res_id})\n"
f"Resource details:\n{vars(resource)}\n"
f"Property details:\n" + "\n".join([str(vars(prop)) for prop in resource.properties])
)
logger.warning(log_msg, exc_info=True)
return None
except Exception as err:
msg = f"Unable to create resource '{resource.label}' ({resource.res_id})"
print(f"{datetime.now()}: WARNING: {msg}: {err}")
msg = f"{datetime.now()}: WARNING: Unable to create resource '{resource.label}' ({resource.res_id})"
if isinstance(err, BaseError):
msg = f"{msg}: {err.message}"
print(msg)
log_msg = (
f"Unable to create resource '{resource.label}' ({resource.res_id})\n"
f"Resource details:\n{vars(resource)}\n"
Expand All @@ -390,7 +381,7 @@ def _create_resource(


def _handle_upload_error(
err: BaseException,
err_msg: str,
iri_resolver: IriResolver,
failed_uploads: list[str],
stash: Stash | None,
Expand All @@ -407,7 +398,7 @@ def _handle_upload_error(
It then quits the Python interpreter with exit code 1.
Args:
err: error that was the cause of the abort
err_msg: string representation of the error that was the cause of the abort
iri_resolver: a resolver for internal IDs to IRIs
failed_uploads: resources that caused an error when uploading to DSP
stash: an object that contains all stashed links that could not be reapplied to their resources
Expand All @@ -417,10 +408,10 @@ def _handle_upload_error(
print(
f"\n==========================================\n"
f"{datetime.now()}: xmlupload must be aborted because of an error.\n"
f"Error message: '{err}'\n"
f"Error message: '{err_msg}'\n"
f"For more information, see the log file: {logfiles}\n"
)
logger.error("xmlupload must be aborted because of an error", exc_info=err)
logger.exception("xmlupload must be aborted because of an error")

timestamp = diagnostics.timestamp_str
servername = diagnostics.server_as_foldername
Expand Down
2 changes: 1 addition & 1 deletion src/dsp_tools/utils/create_logger.py
Expand Up @@ -26,7 +26,7 @@ def _make_handler(
Returns:
handler instance
"""
formatter = logging.Formatter(fmt="{asctime} {filename: <30} {levelname: <8} {message}", style="{")
formatter = logging.Formatter(fmt="{asctime} {filename: <30} l. {lineno: >4} {levelname: <8} {message}", style="{")
formatter.default_time_format = "%Y-%m-%d %H:%M:%S"
formatter.default_msec_format = "%s.%03d"

Expand Down
5 changes: 2 additions & 3 deletions src/dsp_tools/utils/shared.py
Expand Up @@ -244,10 +244,9 @@ def parse_json_input(project_file_as_path_or_parsed: Union[str, Path, dict[str,
with open(project_file_as_path_or_parsed, encoding="utf-8") as f:
try:
project_definition = json.load(f)
except json.JSONDecodeError:
except json.JSONDecodeError as e:
msg = f"The input file '{project_file_as_path_or_parsed}' cannot be parsed to a JSON object."
logger.error(msg, exc_info=True)
raise BaseError(msg) from None
raise BaseError(msg) from e
else:
raise BaseError("Invalid input: The input must be a path to a JSON file or a parsed JSON object.")
return project_definition
Expand Down

0 comments on commit 0025784

Please sign in to comment.