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

Problematy / goodmap / 20583667939

29 Dec 2025 10:04PM UTC coverage: 96.345% (-2.4%) from 98.783%
20583667939

Pull #278

github

web-flow
Merge eecfbbb18 into 783f855e7
Pull Request #278: chore: better errors handling

559 of 590 branches covered (94.75%)

Branch coverage included in aggregate %.

138 of 168 new or added lines in 4 files covered. (82.14%)

1 existing line in 1 file now uncovered.

1260 of 1298 relevant lines covered (97.07%)

0.97 hits per line

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

83.33
/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✔
NEW
14
        return "<unknown>"
×
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
NEW
47
        if self.uuid and self.uuid not in ("<unknown>", "<invalid-uuid>"):
×
NEW
48
            return f"Validation failed for location '{self.uuid}'"
×
NEW
49
        return "Validation failed"
×
50

51

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

55
    pass
1✔
56

57

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

61
    def __init__(self, uuid: str):
1✔
62
        self.uuid = _sanitize_uuid(uuid)
1✔
63
        super().__init__(f"Location with uuid '{self.uuid}' not found")
1✔
64

65

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

69
    pass
1✔
70

71

72
class LocationAlreadyExistsError(AlreadyExistsError):
1✔
73
    """Location with specified UUID already exists."""
1✔
74

75
    def __init__(self, uuid: str):
1✔
76
        self.uuid = _sanitize_uuid(uuid)
1✔
77
        super().__init__(f"Location with uuid '{self.uuid}' already exists")
1✔
78

79

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

83
    def __init__(self, uuid: str):
1✔
NEW
84
        self.uuid = _sanitize_uuid(uuid)
×
NEW
85
        super().__init__(f"Suggestion with uuid '{self.uuid}' not found")
×
86

87

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

91
    def __init__(self, uuid: str):
1✔
92
        self.uuid = _sanitize_uuid(uuid)
1✔
93
        super().__init__(f"Suggestion with uuid '{self.uuid}' already exists")
1✔
94

95

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

99
    def __init__(self, uuid: str):
1✔
NEW
100
        self.uuid = _sanitize_uuid(uuid)
×
NEW
101
        super().__init__(f"Report with uuid '{self.uuid}' not found")
×
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