Skip to content

Commit a99b09d

Browse files
committed
Rename RepositoryError to MetadataError
RepositoryErrors are errors that could be thrown not only in the future repository code, but in the client as well. For example the Updater.referesh(), Updater.get_targetinfo() and Updater.download_target() API calls all throw RepositoryError exception. This could be seen as strange behavior from the user who will use the client code. That's why it makes sense to rename this error to something more generic as "MetadataError" which will denote errors from the client as well as from the repository. Signed-off-by: Martin Vrachev <[email protected]>
1 parent f9211f4 commit a99b09d

8 files changed

+59
-60
lines changed

examples/client_example/client_example.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
import shutil
1111
from pathlib import Path
1212

13-
from tuf.api.exceptions import RepositoryError
13+
from tuf.api.exceptions import MetadataError
1414
from tuf.ngclient import Updater
1515

1616
# constants
@@ -73,7 +73,7 @@ def download(target: str) -> bool:
7373
path = updater.download_target(info)
7474
print(f"Target downloaded and available in {path}")
7575

76-
except (OSError, RepositoryError) as e:
76+
except (OSError, MetadataError) as e:
7777
print(str(e))
7878
return False
7979

tests/test_trusted_metadata_set.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ def test_root_with_invalid_json(self) -> None:
192192
# Test loading initial root and root update
193193
for test_func in [TrustedMetadataSet, self.trusted_set.update_root]:
194194
# root is not json
195-
with self.assertRaises(exceptions.RepositoryError):
195+
with self.assertRaises(exceptions.MetadataError):
196196
test_func(b"")
197197

198198
# root is invalid
@@ -202,7 +202,7 @@ def test_root_with_invalid_json(self) -> None:
202202
test_func(root.to_bytes())
203203

204204
# metadata is of wrong type
205-
with self.assertRaises(exceptions.RepositoryError):
205+
with self.assertRaises(exceptions.MetadataError):
206206
test_func(self.metadata[Snapshot.type])
207207

208208
def test_top_level_md_with_invalid_json(self) -> None:
@@ -214,7 +214,7 @@ def test_top_level_md_with_invalid_json(self) -> None:
214214
for metadata, update_func in top_level_md:
215215
md = Metadata.from_bytes(metadata)
216216
# metadata is not json
217-
with self.assertRaises(exceptions.RepositoryError):
217+
with self.assertRaises(exceptions.MetadataError):
218218
update_func(b"")
219219

220220
# metadata is invalid
@@ -223,7 +223,7 @@ def test_top_level_md_with_invalid_json(self) -> None:
223223
update_func(md.to_bytes())
224224

225225
# metadata is of wrong type
226-
with self.assertRaises(exceptions.RepositoryError):
226+
with self.assertRaises(exceptions.MetadataError):
227227
update_func(self.metadata[Root.type])
228228

229229
update_func(metadata)
@@ -305,7 +305,7 @@ def modify_snapshot_length(timestamp: Timestamp) -> None:
305305
timestamp = self.modify_metadata(Timestamp.type, modify_snapshot_length)
306306
self.trusted_set.update_timestamp(timestamp)
307307

308-
with self.assertRaises(exceptions.RepositoryError):
308+
with self.assertRaises(exceptions.MetadataError):
309309
self.trusted_set.update_snapshot(self.metadata[Snapshot.type])
310310

311311
def test_update_snapshot_fail_threshold_verification(self) -> None:
@@ -342,7 +342,7 @@ def remove_file_from_meta(snapshot: Snapshot) -> None:
342342

343343
# Test removing a meta_file in new_snapshot compared to the old snapshot
344344
snapshot = self.modify_metadata(Snapshot.type, remove_file_from_meta)
345-
with self.assertRaises(exceptions.RepositoryError):
345+
with self.assertRaises(exceptions.MetadataError):
346346
self.trusted_set.update_snapshot(snapshot)
347347

348348
def test_update_snapshot_meta_version_decreases(self) -> None:
@@ -405,7 +405,7 @@ def no_meta_modifier(snapshot: Snapshot) -> None:
405405
self.metadata[Timestamp.type], snapshot
406406
)
407407
# remove meta information with information about targets from snapshot
408-
with self.assertRaises(exceptions.RepositoryError):
408+
with self.assertRaises(exceptions.MetadataError):
409409
self.trusted_set.update_targets(self.metadata[Targets.type])
410410

411411
def test_update_targets_hash_diverge_from_snapshot_meta_hash(self) -> None:
@@ -418,7 +418,7 @@ def meta_length_modifier(snapshot: Snapshot) -> None:
418418
self.metadata[Timestamp.type], snapshot
419419
)
420420
# observed_hash != stored hash in snapshot meta for targets
421-
with self.assertRaises(exceptions.RepositoryError):
421+
with self.assertRaises(exceptions.MetadataError):
422422
self.trusted_set.update_targets(self.metadata[Targets.type])
423423

424424
def test_update_targets_version_diverge_snapshot_meta_version(self) -> None:

tests/test_updater_fetch_target.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
from tests import utils
1717
from tests.repository_simulator import RepositorySimulator
18-
from tuf.api.exceptions import RepositoryError
18+
from tuf.api.exceptions import MetadataError
1919
from tuf.ngclient import Updater
2020

2121

@@ -135,12 +135,12 @@ def test_invalid_target_download(self) -> None:
135135

136136
# Corrupt the file content to not match the hash
137137
self.sim.target_files[target.path].data = b"conten@"
138-
with self.assertRaises(RepositoryError):
138+
with self.assertRaises(MetadataError):
139139
updater.download_target(info)
140140

141141
# Corrupt the file content to not match the length
142142
self.sim.target_files[target.path].data = b"cont"
143-
with self.assertRaises(RepositoryError):
143+
with self.assertRaises(MetadataError):
144144
updater.download_target(info)
145145

146146
# Verify the file is not persisted in cache

tests/test_updater_ng.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -295,11 +295,11 @@ def test_length_hash_mismatch(self) -> None:
295295
assert isinstance(targetinfo, TargetFile)
296296

297297
length = targetinfo.length
298-
with self.assertRaises(exceptions.RepositoryError):
298+
with self.assertRaises(exceptions.MetadataError):
299299
targetinfo.length = 44
300300
self.updater.download_target(targetinfo)
301301

302-
with self.assertRaises(exceptions.RepositoryError):
302+
with self.assertRaises(exceptions.MetadataError):
303303
targetinfo.length = length
304304
targetinfo.hashes = {"sha256": "abcd"}
305305
self.updater.download_target(targetinfo)

tests/test_updater_top_level_update.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
from tuf.api.exceptions import (
2020
BadVersionNumberError,
2121
ExpiredMetadataError,
22-
RepositoryError,
22+
MetadataError,
2323
UnsignedMetadataError,
2424
)
2525
from tuf.api.metadata import (
@@ -389,7 +389,7 @@ def test_new_snapshot_hash_mismatch(self) -> None:
389389
self.sim.timestamp.version += 1 # timestamp v3
390390

391391
# Hash mismatch error
392-
with self.assertRaises(RepositoryError):
392+
with self.assertRaises(MetadataError):
393393
self._run_refresh()
394394

395395
self._assert_version_equals(Timestamp.type, 3)
@@ -495,7 +495,7 @@ def test_new_targets_hash_mismatch(self) -> None:
495495
self.sim.snapshot.version += 1
496496
self.sim.update_timestamp()
497497

498-
with self.assertRaises(RepositoryError):
498+
with self.assertRaises(MetadataError):
499499
self._run_refresh()
500500

501501
self._assert_version_equals(Snapshot.type, 3)

tuf/api/exceptions.py

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,31 +15,30 @@
1515
# pylint: disable=unused-import
1616
from securesystemslib.exceptions import UnsupportedAlgorithmError
1717

18-
19-
class LengthOrHashMismatchError(Exception):
20-
"""An error while checking the length and hash values of an object."""
21-
22-
23-
#### Repository errors ####
18+
#### MetadataError errors ####
2419

2520

26-
class RepositoryError(Exception):
21+
class MetadataError(Exception):
2722
"""An error with a repository's state, such as a missing file."""
2823

2924

30-
class UnsignedMetadataError(RepositoryError):
25+
class UnsignedMetadataError(MetadataError):
3126
"""An error about metadata object with insufficient threshold of
3227
signatures."""
3328

3429

35-
class BadVersionNumberError(RepositoryError):
30+
class BadVersionNumberError(MetadataError):
3631
"""An error for metadata that contains an invalid version number."""
3732

3833

39-
class ExpiredMetadataError(RepositoryError):
34+
class ExpiredMetadataError(MetadataError):
4035
"""Indicate that a TUF Metadata file has expired."""
4136

4237

38+
class LengthOrHashMismatchError(MetadataError):
39+
"""An error while checking the length and hash values of an object."""
40+
41+
4342
#### Download Errors ####
4443

4544

tuf/ngclient/_internal/trusted_metadata_set.py

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
3131
Example of loading root, timestamp and snapshot:
3232
33-
>>> # Load local root (RepositoryErrors here stop the update)
33+
>>> # Load local root (MetadataError here stop the update)
3434
>>> with open(root_path, "rb") as f:
3535
>>> trusted_set = TrustedMetadataSet(f.read())
3636
>>>
@@ -42,7 +42,7 @@
4242
>>> try:
4343
>>> with open(timestamp_path, "rb") as f:
4444
>>> trusted_set.update_timestamp(f.read())
45-
>>> except (RepositoryError, OSError):
45+
>>> except (MetadataError, OSError):
4646
>>> pass # failure to load a local file is ok
4747
>>>
4848
>>> with download(Timestamp.type) as f:
@@ -52,15 +52,15 @@
5252
>>> try:
5353
>>> with open(snapshot_path, "rb") as f:
5454
>>> trusted_set.update_snapshot(f.read())
55-
>>> except (RepositoryError, OSError):
55+
>>> except (MetadataError, OSError):
5656
>>> # local snapshot is not valid, load from remote
57-
>>> # (RepositoryErrors here stop the update)
57+
>>> # (MetadataError here stop the update)
5858
>>> with download(Snapshot.type, version) as f:
5959
>>> trusted_set.update_snapshot(f.read())
6060
6161
TODO:
6262
* exceptions are not final: the idea is that client could just handle
63-
a generic RepositoryError that covers every issue that server provided
63+
a generic MetadataError that covers every issue that server provided
6464
metadata could inflict (other errors would be user errors), but this is not
6565
yet the case
6666
* Progress through Specification update process should be documented
@@ -96,7 +96,7 @@ def __init__(self, root_data: bytes):
9696
all metadata in the TrustedMetadataSet
9797
9898
Raises:
99-
RepositoryError: Metadata failed to load or verify. The actual
99+
MetadataVerificationError: Metadata failed to load or verify. The actual
100100
error type and content will contain more details.
101101
"""
102102
self._trusted_set: Dict[str, Metadata] = {}
@@ -151,7 +151,7 @@ def update_root(self, data: bytes) -> Metadata[Root]:
151151
data: unverified new root metadata as bytes
152152
153153
Raises:
154-
RepositoryError: Metadata failed to load or verify. The actual
154+
MetadataError: Metadata failed to load or verify. The actual
155155
error type and content will contain more details.
156156
157157
Returns:
@@ -164,10 +164,10 @@ def update_root(self, data: bytes) -> Metadata[Root]:
164164
try:
165165
new_root = Metadata[Root].from_bytes(data)
166166
except DeserializationError as e:
167-
raise exceptions.RepositoryError("Failed to load root") from e
167+
raise exceptions.MetadataError("Failed to load root") from e
168168

169169
if new_root.signed.type != Root.type:
170-
raise exceptions.RepositoryError(
170+
raise exceptions.MetadataError(
171171
f"Expected 'root', got '{new_root.signed.type}'"
172172
)
173173

@@ -202,7 +202,7 @@ def update_timestamp(self, data: bytes) -> Metadata[Timestamp]:
202202
data: unverified new timestamp metadata as bytes
203203
204204
Raises:
205-
RepositoryError: Metadata failed to load or verify as final
205+
MetadataError: Metadata failed to load or verify as final
206206
timestamp. The actual error type and content will contain
207207
more details.
208208
@@ -221,10 +221,10 @@ def update_timestamp(self, data: bytes) -> Metadata[Timestamp]:
221221
try:
222222
new_timestamp = Metadata[Timestamp].from_bytes(data)
223223
except DeserializationError as e:
224-
raise exceptions.RepositoryError("Failed to load timestamp") from e
224+
raise exceptions.MetadataError("Failed to load timestamp") from e
225225

226226
if new_timestamp.signed.type != Timestamp.type:
227-
raise exceptions.RepositoryError(
227+
raise exceptions.MetadataError(
228228
f"Expected 'timestamp', got '{new_timestamp.signed.type}'"
229229
)
230230

@@ -288,7 +288,7 @@ def update_snapshot(
288288
match data. Default is False.
289289
290290
Raises:
291-
RepositoryError: data failed to load or verify as final snapshot.
291+
MetadataError: data failed to load or verify as final snapshot.
292292
The actual error type and content will contain more details.
293293
294294
Returns:
@@ -312,17 +312,17 @@ def update_snapshot(
312312
try:
313313
snapshot_meta.verify_length_and_hashes(data)
314314
except exceptions.LengthOrHashMismatchError as e:
315-
raise exceptions.RepositoryError(
315+
raise exceptions.MetadataError(
316316
"Snapshot length or hashes do not match"
317317
) from e
318318

319319
try:
320320
new_snapshot = Metadata[Snapshot].from_bytes(data)
321321
except DeserializationError as e:
322-
raise exceptions.RepositoryError("Failed to load snapshot") from e
322+
raise exceptions.MetadataError("Failed to load snapshot") from e
323323

324324
if new_snapshot.signed.type != Snapshot.type:
325-
raise exceptions.RepositoryError(
325+
raise exceptions.MetadataError(
326326
f"Expected 'snapshot', got '{new_snapshot.signed.type}'"
327327
)
328328

@@ -338,7 +338,7 @@ def update_snapshot(
338338

339339
# Prevent removal of any metadata in meta
340340
if new_fileinfo is None:
341-
raise exceptions.RepositoryError(
341+
raise exceptions.MetadataError(
342342
f"New snapshot is missing info for '{filename}'"
343343
)
344344

@@ -381,7 +381,7 @@ def update_targets(self, data: bytes) -> Metadata[Targets]:
381381
data: unverified new targets metadata as bytes
382382
383383
Raises:
384-
RepositoryError: Metadata failed to load or verify. The actual
384+
MetadataError: Metadata failed to load or verify. The actual
385385
error type and content will contain more details.
386386
387387
Returns:
@@ -400,7 +400,7 @@ def update_delegated_targets(
400400
delegator_name: The name of the role delegating to the new metadata
401401
402402
Raises:
403-
RepositoryError: Metadata failed to load or verify. The actual
403+
MetadataError: Metadata failed to load or verify. The actual
404404
error type and content will contain more details.
405405
406406
Returns:
@@ -422,24 +422,24 @@ def update_delegated_targets(
422422
# Verify against the hashes in snapshot, if any
423423
meta = self.snapshot.signed.meta.get(f"{role_name}.json")
424424
if meta is None:
425-
raise exceptions.RepositoryError(
425+
raise exceptions.MetadataError(
426426
f"Snapshot does not contain information for '{role_name}'"
427427
)
428428

429429
try:
430430
meta.verify_length_and_hashes(data)
431431
except exceptions.LengthOrHashMismatchError as e:
432-
raise exceptions.RepositoryError(
432+
raise exceptions.MetadataError(
433433
f"{role_name} length or hashes do not match"
434434
) from e
435435

436436
try:
437437
new_delegate = Metadata[Targets].from_bytes(data)
438438
except DeserializationError as e:
439-
raise exceptions.RepositoryError("Failed to load snapshot") from e
439+
raise exceptions.MetadataError("Failed to load snapshot") from e
440440

441441
if new_delegate.signed.type != Targets.type:
442-
raise exceptions.RepositoryError(
442+
raise exceptions.MetadataError(
443443
f"Expected 'targets', got '{new_delegate.signed.type}'"
444444
)
445445

@@ -468,10 +468,10 @@ def _load_trusted_root(self, data: bytes) -> None:
468468
try:
469469
new_root = Metadata[Root].from_bytes(data)
470470
except DeserializationError as e:
471-
raise exceptions.RepositoryError("Failed to load root") from e
471+
raise exceptions.MetadataError("Failed to load root") from e
472472

473473
if new_root.signed.type != Root.type:
474-
raise exceptions.RepositoryError(
474+
raise exceptions.MetadataError(
475475
f"Expected 'root', got '{new_root.signed.type}'"
476476
)
477477

0 commit comments

Comments
 (0)