Skip to content

Commit 59d1868

Browse files
authored
Include href when schema resolution fails (#1263)
* fix(spell): test name * feat: report href when failing to fetch schema
1 parent e456289 commit 59d1868

File tree

5 files changed

+31
-2
lines changed

5 files changed

+31
-2
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
### Changed
1212

1313
- `validate_all` now accepts a `STACObject` (in addition to accepting a dict, which is now deprecated), but prohibits supplying a value for `href`, which must be supplied _only_ when supplying an object as a dict. Once `validate_all` removes support for an object as a dict, the `href` parameter will also be removed. ([#1246](https://github.com/stac-utils/pystac/pull/1246))
14+
- Report `href` when schema url resolution fails ([#1263](https://github.com/stac-utils/pystac/pull/1263))
1415

1516
### Fixed
1617

pyproject.toml

+1
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ test = [
5353
"pytest-mock~=3.10",
5454
"pytest-recording~=0.13.0",
5555
"pytest~=7.3",
56+
"requests-mock~=1.11",
5657
"ruff==0.0.292",
5758
"types-html5lib~=1.1",
5859
"types-orjson~=3.6",

pystac/validation/__init__.py

+4
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from pystac.stac_object import STACObjectType
1010
from pystac.utils import make_absolute_href
1111
from pystac.validation.schema_uri_map import OldExtensionSchemaUriMap
12+
from pystac.validation.stac_validator import GetSchemaError
1213

1314
if TYPE_CHECKING:
1415
from pystac.stac_object import STACObject
@@ -245,3 +246,6 @@ def set_validator(validator: STACValidator) -> None:
245246
validation.
246247
"""
247248
RegisteredValidator.set_validator(validator)
249+
250+
251+
__all__ = ["GetSchemaError"]

pystac/validation/stac_validator.py

+11-1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,13 @@
2525
logger = logging.getLogger(__name__)
2626

2727

28+
class GetSchemaError(Exception):
29+
"""Raised when unable to fetch a schema."""
30+
31+
def __init__(self, href: str, error: Exception) -> None:
32+
super().__init__(f"Error when fetching schema {href}: {error}")
33+
34+
2835
class STACValidator(ABC):
2936
"""STACValidator defines methods for validating STAC
3037
JSON. Implementations define methods for validating core objects and extension.
@@ -155,7 +162,10 @@ def __init__(self, schema_uri_map: Optional[SchemaUriMap] = None) -> None:
155162

156163
def _get_schema(self, schema_uri: str) -> dict[str, Any]:
157164
if schema_uri not in self.schema_cache:
158-
s = json.loads(pystac.StacIO.default().read_text(schema_uri))
165+
try:
166+
s = json.loads(pystac.StacIO.default().read_text(schema_uri))
167+
except Exception as error:
168+
raise GetSchemaError(schema_uri, error) from error
159169
self.schema_cache[schema_uri] = s
160170
id_field = "$id" if "$id" in s else "id"
161171
if not s[id_field].startswith("http"):

tests/validation/test_validate.py

+14-1
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,14 @@
77

88
import jsonschema
99
import pytest
10+
from requests_mock import Mocker
1011

1112
import pystac
1213
import pystac.validation
1314
from pystac.cache import CollectionCache
1415
from pystac.serialization.common_properties import merge_common_properties
1516
from pystac.utils import get_opt
17+
from pystac.validation import GetSchemaError
1618
from tests.utils import TestCases
1719
from tests.utils.test_cases import ExampleInfo
1820

@@ -188,10 +190,21 @@ def test_catalog_latest_version_uses_local(catalog: pystac.Catalog) -> None:
188190

189191

190192
@pytest.mark.block_network
191-
def test_collection_latest_versio_uses_localn(collection: pystac.Collection) -> None:
193+
def test_collection_latest_version_uses_local(collection: pystac.Collection) -> None:
192194
assert collection.validate()
193195

194196

195197
@pytest.mark.block_network
196198
def test_item_latest_version_uses_local(item: pystac.Item) -> None:
197199
assert item.validate()
200+
201+
202+
def test_404_schema_url(requests_mock: Mocker, item: pystac.Item) -> None:
203+
requests_mock.get(
204+
"http://pystac-extensions.test/a-fake-schema.json", status_code=404
205+
)
206+
item.stac_extensions = ["http://pystac-extensions.test/a-fake-schema.json"]
207+
with pytest.raises(
208+
GetSchemaError, match="http://pystac-extensions.test/a-fake.schema.json"
209+
):
210+
item.validate()

0 commit comments

Comments
 (0)