Skip to content

Commit 2f3c8a2

Browse files
committed
Add a function to handle errors more descriptively
1 parent 5b96881 commit 2f3c8a2

File tree

4 files changed

+69
-6
lines changed

4 files changed

+69
-6
lines changed

pyproject.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,6 @@ ignore = [
219219
# pydocstyle
220220
"D107", # Missing docstring in __init__
221221
"D417", # Missing argument descriptions in the docstring, this is a bug from pydocstyle: https://github.com/PyCQA/pydocstyle/issues/449
222-
"PD901",
223222
"PD101",
224223
]
225224

sdv/datasets/demo.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import os
77
import warnings
88
from collections import defaultdict
9+
from functools import wraps
910
from pathlib import Path
1011
from zipfile import ZipFile
1112

@@ -171,6 +172,56 @@ def is_direct_json_under_prefix(key):
171172
)
172173

173174

175+
def handle_download_failure():
176+
"""Decorator to handle download exceptions.
177+
178+
Returns:
179+
func:
180+
A wrapped function.
181+
"""
182+
183+
def decorator(func):
184+
@wraps(func)
185+
def wrapper(*args, **kwargs):
186+
try:
187+
function_result = func(*args, **kwargs)
188+
except DemoResourceNotFoundError as error:
189+
bucket = kwargs.get('bucket', args[2])
190+
dataset_name = kwargs.get('dataset_name', args[1])
191+
error_msg = error.message
192+
if 'No objects found under' in error_msg:
193+
raise DemoResourceNotFoundError(
194+
f'Could not download dataset {dataset_name} from bucket {bucket}. '
195+
'Make sure the bucket name is correct. If the bucket is private '
196+
'make sure to provide your credentials.'
197+
) from error
198+
199+
if 'METADATA_SPEC_VERSION' in error_msg or 'metadata' in error_msg:
200+
raise DemoResourceNotFoundError(
201+
f'Could not download dataset {dataset_name} from bucket {bucket}. '
202+
'The dataset is missing a valid metadata.'
203+
) from error
204+
205+
if 'no csv files were found in data.zip' in error_msg:
206+
raise DemoResourceNotFoundError(
207+
f'Could not download dataset {dataset_name} from bucket {bucket}. '
208+
'The dataset is missing `csv` file/s.'
209+
) from error
210+
211+
if "Could not find 'data.zip'" in error_msg:
212+
raise DemoResourceNotFoundError(
213+
f'Could not download dataset {dataset_name} from bucket {bucket}. '
214+
"The dataset is missing 'data.zip' file."
215+
) from error
216+
217+
return function_result
218+
219+
return wrapper
220+
221+
return decorator
222+
223+
224+
@handle_download_failure()
174225
def _download(modality, dataset_name, bucket, credentials=None):
175226
"""Download dataset resources from a bucket.
176227

sdv/errors.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,10 @@ class DemoResourceNotFoundError(Exception):
104104
metadata, license, README, or other auxiliary files in the demo bucket.
105105
"""
106106

107+
def __init__(self, message):
108+
self.message = message
109+
super().__init__(self.message)
110+
107111

108112
class DemoResourceNotFoundWarning(UserWarning):
109113
"""Warning raised when an optional demo resource is not available.

tests/unit/datasets/test_demo.py

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ def _make_zip_with_csv(csv_name: str, df: pd.DataFrame) -> bytes:
3030
buf = io.BytesIO()
3131
with zipfile.ZipFile(buf, mode='w', compression=zipfile.ZIP_DEFLATED) as zf:
3232
zf.writestr(csv_name, df.to_csv(index=False))
33+
3334
return buf.getvalue()
3435

3536

@@ -80,6 +81,7 @@ def side_effect(key, bucket='test_bucket', client=None):
8081
return zip_bytes
8182
if key.endswith('metadata.json'):
8283
return meta_bytes
84+
8385
raise KeyError(key)
8486

8587
mock_get.side_effect = side_effect
@@ -608,16 +610,19 @@ def side_effect(key, bucket, client):
608610
assert metadata.to_dict()['tables']['word']['primary_key'] == 'id'
609611

610612

611-
@patch('sdv.datasets.demo._get_data_from_bucket', return_value=b'{}')
612613
@patch('sdv.datasets.demo._list_objects')
613-
def test_download_demo_missing_zip_raises(mock_list, _mock_get):
614+
def test_download_demo_missing_zip_raises(mock_list):
614615
# Setup
615616
mock_list.return_value = [
616617
{'Key': 'single_table/word/metadata.json'},
617618
]
618619

619620
# Run and Assert
620-
with pytest.raises(DemoResourceNotFoundError, match="Could not find 'data.zip'"):
621+
expected_msg = (
622+
'Could not download dataset word from bucket sdv-datasets-public. '
623+
"The dataset is missing 'data.zip' file."
624+
)
625+
with pytest.raises(DemoResourceNotFoundError, match=expected_msg):
621626
download_demo('single_table', 'word')
622627

623628

@@ -634,7 +639,11 @@ def test_download_demo_no_v1_metadata_raises(mock_list, mock_get):
634639
)
635640

636641
# Run and Assert
637-
with pytest.raises(DemoResourceNotFoundError, match='METADATA_SPEC_VERSION'):
642+
error_msg = (
643+
'Could not download dataset word from bucket sdv-datasets-public. '
644+
'The dataset is missing a valid metadata.'
645+
)
646+
with pytest.raises(DemoResourceNotFoundError, match=error_msg):
638647
download_demo('single_table', 'word')
639648

640649

@@ -687,8 +696,8 @@ def test_download_demo_writes_metadata_and_discovers_nested_csv(mock_list, mock_
687696
buf = io.BytesIO()
688697
with zipfile.ZipFile(buf, mode='w', compression=zipfile.ZIP_DEFLATED) as zf:
689698
zf.writestr('level1/level2/my_table.csv', df.to_csv(index=False))
690-
zip_bytes = buf.getvalue()
691699

700+
zip_bytes = buf.getvalue()
692701
meta_dict = {
693702
'METADATA_SPEC_VERSION': 'V1',
694703
'tables': {

0 commit comments

Comments
 (0)