Skip to content

Commit 176aa20

Browse files
committed
Improve error handling
1 parent 8d462c3 commit 176aa20

8 files changed

Lines changed: 61 additions & 37 deletions

File tree

dataverse/__init__.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
from connection import Connection
22
from dataverse import Dataverse
33
from dataset import Dataset
4-
from file import DataverseFile
5-
6-
from utils import DataverseException
4+
from file import DataverseFile

dataverse/connection.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import requests
33

44
from dataverse import Dataverse
5+
from exceptions import DataverseError, UnauthorizedError
56
from utils import get_elements, is_not_root_dataverse
67

78

@@ -32,13 +33,18 @@ def has_api_key(self):
3233

3334
def connect(self):
3435
resp = requests.get(self.sd_uri, auth=self.auth)
35-
self.status = resp.status_code
36-
self.connected = True if self.status == 200 else False
36+
37+
if resp.status_code == 403:
38+
raise UnauthorizedError('The credentials provided are invalid.')
39+
elif resp.status_code != 200:
40+
raise DataverseError('Could not connect to the Dataverse')
41+
42+
self.connected = True
3743
self.service_document = etree.XML(resp.content)
3844

39-
def get_dataverses(self, allow_root=False):
40-
# Get latest dataverse information
41-
self.connect()
45+
def get_dataverses(self, refresh=False, allow_root=False):
46+
if refresh:
47+
self.connect()
4248

4349
collections = get_elements(
4450
self.service_document[0],

dataverse/dataset.py

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,10 @@
55
from lxml import etree
66
import requests
77

8+
from exceptions import DataverseError, MethodNotAllowedError, NoContainerError
89
from file import DataverseFile
910
from settings import SWORD_BOOTSTRAP
10-
from utils import (
11-
get_element, get_elements, DataverseException, get_files_in_path,
12-
add_field,
13-
)
11+
from utils import get_element, get_elements, get_files_in_path, add_field
1412

1513

1614
class Dataset(object):
@@ -93,7 +91,7 @@ def get_entry(self, refresh=False):
9391
resp = requests.get(self.edit_uri, auth=self.connection.auth)
9492

9593
if resp.status_code != 200:
96-
raise DataverseException('Atom entry could not be retrieved.')
94+
raise DataverseError('Atom entry could not be retrieved.')
9795

9896
entry_string = resp.content
9997
self._entry = etree.XML(entry_string)
@@ -103,8 +101,8 @@ def get_statement(self, refresh=False):
103101
if not refresh and self._statement:
104102
return self._statement
105103

106-
if not self.connection:
107-
raise DataverseException('This dataset has not been added to a Dataverse.')
104+
if not self.dataverse:
105+
raise NoContainerError('This dataset has not been added to a Dataverse.')
108106

109107
if not self.statement_uri:
110108
# Try to find statement uri without a request to the server
@@ -127,7 +125,7 @@ def get_statement(self, refresh=False):
127125
resp = requests.get(self.statement_uri, auth=self.connection.auth)
128126

129127
if resp.status_code != 200:
130-
raise DataverseException('Statement could not be retrieved.')
128+
raise DataverseError('Statement could not be retrieved.')
131129

132130
self._statement = resp.content
133131
return self._statement
@@ -228,14 +226,14 @@ def publish(self):
228226
)
229227

230228
if resp.status_code != 200:
231-
raise DataverseException('The Dataverse could not be published.')
229+
raise DataverseError('The Dataverse could not be published.')
232230

233231
receipt = resp.content
234232
self._refresh(receipt=receipt)
235233

236234
def delete_file(self, dataverse_file):
237235
if dataverse_file.is_published:
238-
raise DataverseException(
236+
raise MethodNotAllowedError(
239237
'Published versions of files cannot be deleted.'
240238
)
241239

@@ -245,7 +243,7 @@ def delete_file(self, dataverse_file):
245243
)
246244

247245
if resp.status_code != 204:
248-
raise DataverseException('The file could not be deleted.')
246+
raise DataverseError('The file could not be deleted.')
249247

250248
def delete_all_files(self):
251249
for f in self.get_files():

dataverse/dataverse.py

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import requests
22

33
from dataset import Dataset
4-
from utils import get_element, get_elements, DataverseException, sanitize
4+
from exceptions import DataverseError, InsufficientMetadataError, MethodNotAllowedError
5+
from utils import get_element, get_elements, sanitize
56

67

78
class Dataverse(object):
@@ -49,16 +50,16 @@ def publish(self):
4950
)
5051

5152
if resp.status_code != 200:
52-
raise DataverseException('The Dataverse could not be published.')
53+
raise DataverseError('The Dataverse could not be published.')
5354

5455
def add_dataset(self, dataset):
5556

5657
if get_element(dataset._entry, 'title', 'dcterms') is None:
57-
raise DataverseException('This dataset must have a title.')
58+
raise InsufficientMetadataError('This dataset must have a title.')
5859
if get_element(dataset._entry, 'description', 'dcterms') is None:
59-
raise DataverseException('This dataset must have a description.')
60+
raise InsufficientMetadataError('This dataset must have a description.')
6061
if get_element(dataset._entry, 'creator', 'dcterms') is None:
61-
raise DataverseException('This dataset must have an author.')
62+
raise InsufficientMetadataError('This dataset must have an author.')
6263

6364
resp = requests.post(
6465
self.collection.get('href'),
@@ -68,23 +69,23 @@ def add_dataset(self, dataset):
6869
)
6970

7071
if resp.status_code != 201:
71-
raise DataverseException('This dataset could not be added.')
72+
raise DataverseError('This dataset could not be added.')
7273

7374
dataset.dataverse = self
7475
dataset._refresh(receipt=resp.content)
7576

7677
def delete_dataset(self, dataset):
7778

7879
if dataset._state == 'DELETED' or dataset._state == 'DEACCESSIONED':
79-
raise DataverseException('This dataset has already been deleted.')
80+
return
8081

8182
resp = requests.delete(
8283
dataset.edit_uri,
8384
auth=self.connection.auth,
8485
)
8586
if resp.status_code == 405:
86-
raise DataverseException('Published studies can only be deleted '
87-
'from the GUI. For more information, please refer to '
87+
raise MethodNotAllowedError('Published studies can only be '
88+
'deleted from the GUI. For more information, please refer to '
8889
'https://github.com/IQSS/dataverse/issues/778')
8990

9091
dataset._state = 'DEACCESSIONED'

dataverse/exceptions.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
class DataverseError(Exception):
2+
"""Base exception class for Dataverse-related error."""
3+
pass
4+
5+
6+
class UnauthorizedError(DataverseError):
7+
"""Raised if a user provides invalid credentials."""
8+
pass
9+
10+
11+
class InsufficientMetadataError(DataverseError):
12+
"""Raised if more metadata is required."""
13+
pass
14+
15+
16+
class MethodNotAllowedError(DataverseError):
17+
"""Raised if the attempted method is not allowed"""
18+
pass
19+
20+
21+
class NoContainerError(DataverseError):
22+
"""Raised if a dataset attempts to access the server before it is added to a Dataverse"""
23+
pass

dataverse/file.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import urlparse
22

3-
from utils import DataverseException, get_element, sanitize
3+
from exceptions import InsufficientMetadataError
4+
from utils import get_element, sanitize
45

56

67
class DataverseFile(object):
@@ -21,7 +22,7 @@ def __init__(self, name, dataset, edit_media_uri=None, download_url=None):
2122
self.download_url = download_url
2223
self.id = download_url.split('=')[-1]
2324
else:
24-
raise DataverseException(
25+
raise InsufficientMetadataError(
2526
'Files must have an edit media uri or download url.'
2627
)
2728

dataverse/test/test_dataverse.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@
44
logging.basicConfig(level=logging.ERROR)
55

66
# local modules
7-
from dataverse.dataset import Dataset
87
from dataverse.connection import Connection
8+
from dataverse.dataset import Dataset
9+
from dataverse.exceptions import DataverseError
910
from dataverse.settings import DEFAULT_TOKEN, DEFAULT_HOST
1011
from dataverse.test.config import PICS_OF_CATS_DATASET, ATOM_DATASET
1112
from dataverse import utils
@@ -97,8 +98,8 @@ def setUpClass(self):
9798
print "Getting Dataverse"
9899
dataverses = self.dvc.get_dataverses()
99100
if not dataverses:
100-
raise utils.DataverseException(
101-
'You must have a published Dataverse to run these tests.'
101+
raise DataverseError(
102+
'You must have a Dataverse to run these tests.'
102103
)
103104

104105
self.dv = dataverses[0]

dataverse/utils.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,6 @@
66
from settings import SWORD_NAMESPACE, REPLACEMENT_DICT, UNIQUE_FIELDS
77

88

9-
class DataverseException(Exception):
10-
pass
11-
12-
139
def is_not_root_dataverse(collection):
1410
col_alias = collection.attrib['href'].split('/')[-1]
1511
# Root dataverse may be named differently per host

0 commit comments

Comments
 (0)