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: add 422 Error class and status_code to DataCiteError #99

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
76 changes: 59 additions & 17 deletions datacite/errors.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
# -*- coding: utf-8 -*-

Check failure on line 1 in datacite/errors.py

View workflow job for this annotation

GitHub Actions / Tests (3.9)

pydocstyle-check /home/runner/work/datacite/datacite/datacite/errors.py:1 at module level: D100: Missing docstring in public module /home/runner/work/datacite/datacite/datacite/errors.py:111 in public class `DataCiteErrorFactory`: D400: First line should end with a period (not 'e')

Check failure on line 1 in datacite/errors.py

View workflow job for this annotation

GitHub Actions / Tests (3.12)

pydocstyle-check /home/runner/work/datacite/datacite/datacite/errors.py:1 at module level: D100: Missing docstring in public module /home/runner/work/datacite/datacite/datacite/errors.py:111 in public class `DataCiteErrorFactory`: D400: First line should end with a period (not 'e')
#
# This file is part of DataCite.
#
# Copyright (C) 2015 CERN.
# Copyright (C) 2024 Arizona State University.
#
# DataCite is free software; you can redistribute it and/or modify it
# under the terms of the Revised BSD License; see LICENSE file for
# more details.

from collections import defaultdict

"""Errors for the DataCite API.

MDS error responses will be converted into an exception from this module.
Expand All @@ -32,27 +35,21 @@
* 403 Forbidden
* 404 Not Found
* 410 Gone (deleted)
* 412 Precondition Failed
* 422 Unprocessable Entity
"""

status_code = 400

def __init__(self, *args, status_code=500):
"""Initialize this exception with an http status code error."""
super().__init__(*args)
self.status_code = status_code

@staticmethod
def factory(err_code, *args):
def factory(status_code, *args):
"""Create exceptions through a Factory based on the HTTP error code."""
if err_code == 204:
return DataCiteNoContentError(*args)
elif err_code == 400:
return DataCiteBadRequestError(*args)
elif err_code == 401:
return DataCiteUnauthorizedError(*args)
elif err_code == 403:
return DataCiteForbiddenError(*args)
elif err_code == 404:
return DataCiteNotFoundError(*args)
elif err_code == 410:
return DataCiteGoneError(*args)
elif err_code == 412:
return DataCitePreconditionError(*args)
else:
return DataCiteServerError(*args)
return DataCiteErrorFactory.create(status_code, *args)


class DataCiteServerError(DataCiteError):
Expand Down Expand Up @@ -104,3 +101,48 @@

class DataCitePreconditionError(DataCiteRequestError):
"""Metadata must be uploaded first."""


class DataCiteUnprocessableEntityError(DataCiteRequestError):
"""Invalid metadata format or content."""


class DataCiteErrorFactory:
"""
Factory class to create specific DataCiteError instances based on the HTTP status code

Attributes:
ERROR_CLASSES (defaultdict): A dictionary mapping HTTP status codes to corresponding DataCiteError classes.
"""

ERROR_CLASSES = defaultdict(
lambda status_code: (
DataCiteServerError if status_code >= 500 else DataCiteRequestError
),
{
204: DataCiteNoContentError,
400: DataCiteBadRequestError,
401: DataCiteUnauthorizedError,
403: DataCiteForbiddenError,
404: DataCiteNotFoundError,
410: DataCiteGoneError,
412: DataCitePreconditionError,
422: DataCiteUnprocessableEntityError,
},
)

@staticmethod
def create(status_code, *args):
"""
Create a specific DataCiteError instance based on the provided error code.

Args:
status_code (int): The HTTP status code representing the error.
args: Additional arguments to be passed to the DataCiteError constructor.

Returns:
DataCiteError: An instance of the appropriate DataCiteError subclass.

"""
DataCiteErrorClass = DataCiteErrorFactory.ERROR_CLASSES[status_code]
return DataCiteErrorClass(*args, status_code=status_code)
Loading