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
1315MDS 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
5854class DataCiteServerError (DataCiteError ):
@@ -104,3 +100,48 @@ class DataCiteGoneError(DataCiteRequestError):
104100
105101class 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