• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Problematy / goodmap / 20585330737

29 Dec 2025 11:53PM UTC coverage: 97.841% (-0.9%) from 98.783%
20585330737

Pull #278

github

web-flow
Merge c31622875 into 783f855e7
Pull Request #278: fix: uuid sanitization and better errors handling

560 of 579 branches covered (96.72%)

Branch coverage included in aggregate %.

157 of 172 new or added lines in 4 files covered. (91.28%)

1 existing line in 1 file now uncovered.

1253 of 1274 relevant lines covered (98.35%)

0.98 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

93.85
/goodmap/exceptions.py
1
"""Custom exceptions for Goodmap application."""
1✔
2

3
import logging
1✔
4
import uuid as uuid_lib
1✔
5

6
from pydantic import ValidationError as PydanticValidationError
1✔
7

8
logger = logging.getLogger(__name__)
1✔
9

10

11
def _sanitize_uuid(uuid: str | None) -> str:
1✔
12
    """Validate and sanitize UUID to prevent injection attacks."""
13
    if uuid is None:
1✔
14
        return "<unknown>"
1✔
15
    try:
1✔
16
        # Validate UUID format
17
        uuid_lib.UUID(uuid)
1✔
18
        return uuid
1✔
19
    except (ValueError, AttributeError, TypeError):
1✔
20
        logger.warning("Invalid UUID format detected", extra={"raw_uuid": repr(uuid)})
1✔
21
        return "<invalid-uuid>"
1✔
22

23

24
class GoodmapError(Exception):
1✔
25
    """Base exception for all Goodmap errors."""
1✔
26

27
    pass
1✔
28

29

30
class ValidationError(GoodmapError):
1✔
31
    """Base validation error."""
1✔
32

33
    pass
1✔
34

35

36
class LocationValidationError(ValidationError):
1✔
37
    """Validation error for location data with enhanced context."""
1✔
38

39
    def __init__(self, validation_error: PydanticValidationError, uuid: str | None = None):
1✔
40
        self.uuid = _sanitize_uuid(uuid)
1✔
41
        self.original_error = validation_error
1✔
42
        self.validation_errors = validation_error.errors()
1✔
43
        super().__init__(str(validation_error))
1✔
44

45
    def __str__(self):
1✔
46
        # Don't expose error details in string representation
47
        if self.uuid and self.uuid not in ("<unknown>", "<invalid-uuid>"):
1✔
NEW
48
            return f"Validation failed for location '{self.uuid}'"
×
49
        return "Validation failed"
1✔
50

51

52
class NotFoundError(GoodmapError):
1✔
53
    """Resource not found error."""
1✔
54

55
    def __init__(self, uuid: str, resource_type: str = "Resource"):
1✔
56
        self.uuid = _sanitize_uuid(uuid)
1✔
57
        super().__init__(f"{resource_type} with uuid '{self.uuid}' not found")
1✔
58

59

60
class LocationNotFoundError(NotFoundError):
1✔
61
    """Location with specified UUID not found."""
1✔
62

63
    def __init__(self, uuid: str):
1✔
64
        super().__init__(uuid, "Location")
1✔
65

66

67
class AlreadyExistsError(GoodmapError):
1✔
68
    """Resource already exists error."""
1✔
69

70
    def __init__(self, uuid: str, resource_type: str = "Resource"):
1✔
71
        self.uuid = _sanitize_uuid(uuid)
1✔
72
        super().__init__(f"{resource_type} with uuid '{self.uuid}' already exists")
1✔
73

74

75
class LocationAlreadyExistsError(AlreadyExistsError):
1✔
76
    """Location with specified UUID already exists."""
1✔
77

78
    def __init__(self, uuid: str):
1✔
79
        super().__init__(uuid, "Location")
1✔
80

81

82
class SuggestionNotFoundError(NotFoundError):
1✔
83
    """Suggestion with specified UUID not found."""
1✔
84

85
    def __init__(self, uuid: str):
1✔
NEW
86
        super().__init__(uuid, "Suggestion")
×
87

88

89
class SuggestionAlreadyExistsError(AlreadyExistsError):
1✔
90
    """Suggestion with specified UUID already exists."""
1✔
91

92
    def __init__(self, uuid: str):
1✔
NEW
93
        super().__init__(uuid, "Suggestion")
×
94

95

96
class ReportNotFoundError(NotFoundError):
1✔
97
    """Report with specified UUID not found."""
1✔
98

99
    def __init__(self, uuid: str):
1✔
100
        super().__init__(uuid, "Report")
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc