88from packaging .requirements import Requirement
99from rest_framework import serializers
1010from pypi_attestations import AttestationError
11- from pydantic import TypeAdapter , ValidationError
11+ from pydantic import TypeAdapter , ValidationError as PydanticValidationError
1212from urllib .parse import urljoin
1313
14+ from pulpcore .plugin .exceptions import DigestValidationError , ValidationError
1415from pulpcore .plugin import models as core_models
1516from pulpcore .plugin import serializers as core_serializers
1617from pulpcore .plugin .util import get_domain , get_prn , get_current_authenticated_user
1718
1819from pulp_python .app import models as python_models
20+ from pulp_python .app .exceptions import (
21+ AttestationVerificationError ,
22+ InvalidProvenanceError ,
23+ InvalidPythonExtensionError ,
24+ MissingRelativePathError ,
25+ ProvenanceVerificationError ,
26+ )
1927from pulp_python .app .provenance import (
2028 Attestation ,
2129 Provenance ,
@@ -374,7 +382,7 @@ def validate_attestations(self, value):
374382 attestations = TypeAdapter (list [Attestation ]).validate_json (value )
375383 else :
376384 attestations = TypeAdapter (list [Attestation ]).validate_python (value )
377- except ValidationError as e :
385+ except PydanticValidationError as e :
378386 raise serializers .ValidationError (_ ("Invalid attestations: {}" .format (e )))
379387 return attestations
380388
@@ -387,9 +395,7 @@ def handle_attestations(self, filename, sha256, attestations, offline=True):
387395 try :
388396 verify_provenance (filename , sha256 , provenance , offline = offline )
389397 except AttestationError as e :
390- raise serializers .ValidationError (
391- {"attestations" : _ ("Attestations failed verification: {}" .format (e ))}
392- )
398+ raise AttestationVerificationError (str (e ))
393399 return provenance .model_dump (mode = "json" )
394400
395401 def deferred_validate (self , data ):
@@ -408,26 +414,18 @@ def deferred_validate(self, data):
408414 try :
409415 filename = data ["relative_path" ]
410416 except KeyError :
411- raise serializers . ValidationError ( detail = { "relative_path" : _ ( "This field is required" )} )
417+ raise MissingRelativePathError ( )
412418
413419 artifact = data ["artifact" ]
414420 try :
415421 _data = artifact_to_python_content_data (filename , artifact , domain = get_domain ())
416422 except ValueError :
417- raise serializers .ValidationError (
418- _ (
419- "Extension on {} is not a valid python extension "
420- "(.whl, .exe, .egg, .tar.gz, .tar.bz2, .zip)"
421- ).format (filename )
422- )
423+ raise InvalidPythonExtensionError (filename )
423424
424425 if data .get ("sha256" ) and data ["sha256" ] != artifact .sha256 :
425- raise serializers .ValidationError (
426- detail = {
427- "sha256" : _ (
428- "The uploaded artifact's sha256 checksum does not match the one provided"
429- )
430- }
426+ raise DigestValidationError (
427+ actual = artifact .sha256 ,
428+ expected = data ["sha256" ],
431429 )
432430
433431 data .update (_data )
@@ -641,15 +639,13 @@ def deferred_validate(self, data):
641639 try :
642640 provenance = Provenance .model_validate_json (data ["file" ].read ())
643641 data ["provenance" ] = provenance .model_dump (mode = "json" )
644- except ValidationError as e :
645- raise serializers .ValidationError (
646- _ ("The uploaded provenance is not valid: {}" .format (e ))
647- )
642+ except PydanticValidationError as e :
643+ raise InvalidProvenanceError (str (e ))
648644 if data .pop ("verify" ):
649645 try :
650646 verify_provenance (data ["package" ].filename , data ["package" ].sha256 , provenance )
651647 except AttestationError as e :
652- raise serializers . ValidationError ( _ ( "Provenance verification failed: {}" . format ( e ) ))
648+ raise ProvenanceVerificationError ( str ( e ))
653649 return data
654650
655651 def retrieve (self , validated_data ):
0 commit comments