Skip to content

Commit b2ddb55

Browse files
committed
fix: add 422 Error class and status_code to DataCiteError
use a defaultdict to map status codes to error classes, defaults to DataCiteServerError for status_code >= 500 and DataCiteRequestError for all others
1 parent bd2c7d7 commit b2ddb55

1 file changed

Lines changed: 57 additions & 16 deletions

File tree

datacite/errors.py

Lines changed: 57 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
# under the terms of the Revised BSD License; see LICENSE file for
99
# more details.
1010

11+
from collections import defaultdict
12+
1113
"""Errors for the DataCite API.
1214
1315
MDS error responses will be converted into an exception from this module.
@@ -32,27 +34,21 @@ class DataCiteError(Exception):
3234
* 403 Forbidden
3335
* 404 Not Found
3436
* 410 Gone (deleted)
37+
* 412 Precondition Failed
38+
* 422 Unprocessable Entity
3539
"""
3640

41+
status_code = 400
42+
43+
def __init__(self, *args, status_code=500):
44+
"""Initialize this exception with an http status code error."""
45+
super().__init__(*args)
46+
self.status_code = status_code
47+
3748
@staticmethod
3849
def factory(err_code, *args):
3950
"""Create exceptions through a Factory based on the HTTP error code."""
40-
if err_code == 204:
41-
return DataCiteNoContentError(*args)
42-
elif err_code == 400:
43-
return DataCiteBadRequestError(*args)
44-
elif err_code == 401:
45-
return DataCiteUnauthorizedError(*args)
46-
elif err_code == 403:
47-
return DataCiteForbiddenError(*args)
48-
elif err_code == 404:
49-
return DataCiteNotFoundError(*args)
50-
elif err_code == 410:
51-
return DataCiteGoneError(*args)
52-
elif err_code == 412:
53-
return DataCitePreconditionError(*args)
54-
else:
55-
return DataCiteServerError(*args)
51+
return DataCiteErrorFactory.create(err_code, *args)
5652

5753

5854
class DataCiteServerError(DataCiteError):
@@ -104,3 +100,48 @@ class DataCiteGoneError(DataCiteRequestError):
104100

105101
class DataCitePreconditionError(DataCiteRequestError):
106102
"""Metadata must be uploaded first."""
103+
104+
105+
class DataCiteUnprocessableEntityError(DataCiteRequestError):
106+
"""Invalid metadata format or content."""
107+
108+
109+
class DataCiteErrorFactory:
110+
"""
111+
Factory class to create specific DataCiteError instances based on the HTTP status code
112+
113+
Attributes:
114+
ERROR_CLASSES (defaultdict): A dictionary mapping HTTP status codes to corresponding DataCiteError classes.
115+
"""
116+
117+
ERROR_CLASSES = defaultdict(
118+
lambda status_code: (
119+
DataCiteServerError if status_code >= 500 else DataCiteRequestError
120+
),
121+
{
122+
204: DataCiteNoContentError,
123+
400: DataCiteBadRequestError,
124+
401: DataCiteUnauthorizedError,
125+
403: DataCiteForbiddenError,
126+
404: DataCiteNotFoundError,
127+
410: DataCiteGoneError,
128+
412: DataCitePreconditionError,
129+
422: DataCiteUnprocessableEntityError,
130+
},
131+
)
132+
133+
@staticmethod
134+
def create(err_code, *args):
135+
"""
136+
Create a specific DataCiteError instance based on the provided error code.
137+
138+
Args:
139+
err_code (int): The HTTP status code representing the error.
140+
*args: Additional arguments to be passed to the DataCiteError constructor.
141+
142+
Returns:
143+
DataCiteError: An instance of the appropriate DataCiteError subclass.
144+
145+
"""
146+
DataCiteErrorClass = DataCiteErrorFactory.ERROR_CLASSES[err_code]
147+
return DataCiteErrorClass(*args, status_code=err_code)

0 commit comments

Comments
 (0)