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

geo-engine / geoengine-python / 16367912334

18 Jul 2025 10:06AM UTC coverage: 76.934% (+0.1%) from 76.806%
16367912334

push

github

web-flow
ci: use Ruff as new formatter and linter (#233)

* wip

* pycodestyle

* update dependencies

* skl2onnx

* use ruff

* apply formatter

* apply lint auto fixes

* manually apply lints

* change check

* ruff ci from branch

2805 of 3646 relevant lines covered (76.93%)

0.77 hits per line

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

65.42
geoengine/error.py
1
"""
2
Package errors and backend mapped error types
3
"""
4

5
import json
1✔
6
import xml.etree.ElementTree as ET
1✔
7
from typing import Any
1✔
8

9
import geoengine_openapi_client
1✔
10
from requests import HTTPError, Response
1✔
11

12

13
class GeoEngineException(Exception):
1✔
14
    """
15
    Base class for exceptions from the backend
16
    """
17

18
    error: str
1✔
19
    message: str
1✔
20

21
    def __init__(self, response: geoengine_openapi_client.ApiException | dict[str, str]) -> None:
1✔
22
        super().__init__()
1✔
23

24
        if isinstance(response, geoengine_openapi_client.ApiException):
1✔
25
            obj = json.loads(response.body) if response.body else {"error": "unknown", "message": "unknown"}
×
26
        else:
27
            obj = response
1✔
28

29
        self.error = obj.get("error", "?")
1✔
30
        self.message = obj.get("message", "?")
1✔
31

32
    def __str__(self) -> str:
1✔
33
        return f"{self.error}: {self.message}"
×
34

35

36
class InputException(Exception):
1✔
37
    """
38
    Exception that is thrown on wrong inputs
39
    """
40

41
    __message: str
1✔
42

43
    def __init__(self, message: str) -> None:
1✔
44
        super().__init__()
1✔
45

46
        self.__message = message
1✔
47

48
    def __str__(self) -> str:
1✔
49
        return f"{self.__message}"
1✔
50

51

52
class UninitializedException(Exception):
1✔
53
    """
54
    Exception that is thrown when there is no connection to the backend but methods on the backend are called
55
    """
56

57
    def __str__(self) -> str:
1✔
58
        return "You have to call `initialize` before using other functionality"
1✔
59

60

61
class TypeException(Exception):
1✔
62
    """
63
    Exception on wrong types of input
64
    """
65

66
    __message: str
1✔
67

68
    def __init__(self, message: str) -> None:
1✔
69
        super().__init__()
×
70

71
        self.__message = message
×
72

73
    def __str__(self) -> str:
1✔
74
        return f"{self.__message}"
×
75

76

77
class ModificationNotOnLayerDbException(Exception):
1✔
78
    """
79
    Exception that is when trying to modify layers that are not part of the layerdb
80
    """
81

82
    __message: str
1✔
83

84
    def __init__(self, message: str) -> None:
1✔
85
        super().__init__()
×
86

87
        self.__message = message
×
88

89
    def __str__(self) -> str:
1✔
90
        return f"{self.__message}"
×
91

92

93
# TODO: remove methods and forbid calling methods in the first place
94

95

96
class MethodNotCalledOnRasterException(Exception):
1✔
97
    """
98
    Exception for calling a raster method on a, e.g., vector layer
99
    """
100

101
    def __str__(self) -> str:
1✔
102
        return "Only allowed to call method on raster result"
×
103

104

105
# TODO: remove methods and forbid calling methods in the first place
106
class MethodNotCalledOnVectorException(Exception):
1✔
107
    """
108
    Exception for calling a vector method on a, e.g., raster layer
109
    """
110

111
    def __str__(self) -> str:
1✔
112
        return "Only allowed to call method on vector result"
×
113

114

115
# TODO: remove methods and forbid calling methods in the first place
116
class MethodNotCalledOnPlotException(Exception):
1✔
117
    """
118
    Exception for calling a plot method on a, e.g., vector layer
119
    """
120

121
    def __str__(self) -> str:
1✔
122
        return "Only allowed to call method on plot result"
×
123

124

125
class SpatialReferenceMismatchException(Exception):
1✔
126
    """
127
    Exception for calling a method on a workflow with a query rectangle that has a different spatial reference
128
    """
129

130
    def __init__(self, spatial_reference_a: str, spatial_reference_b: str) -> None:
1✔
131
        super().__init__()
×
132

133
        self.__spatial_reference_a = spatial_reference_a
×
134
        self.__spatial_reference_b = spatial_reference_b
×
135

136
    def __str__(self) -> str:
1✔
137
        return f"Spatial reference mismatch {self.__spatial_reference_a} != {self.__spatial_reference_b}"
×
138

139

140
class InvalidUrlException(Exception):
1✔
141
    """
142
    Exception for when no valid url is provided
143
    """
144

145
    def __init__(self, msg: str) -> None:
1✔
146
        super().__init__()
×
147

148
        self.__msg = msg
×
149

150
    def __str__(self) -> str:
1✔
151
        return f"{self.__msg}"
×
152

153

154
class MissingFieldInResponseException(Exception):
1✔
155
    """
156
    Exception for when a field is missing in a response
157
    """
158

159
    missing_field: str
1✔
160
    response: Any
1✔
161

162
    def __init__(self, missing_field: str, response: Any) -> None:
1✔
163
        super().__init__()
×
164

165
        self.missing_field = missing_field
×
166
        self.response = response
×
167

168
    def __str__(self) -> str:
1✔
169
        return f"Missing field '{self.missing_field}' in response: {self.response}"
×
170

171

172
def check_response_for_error(response: Response) -> None:
1✔
173
    """
174
    Checks a `Response` for an error and raises it if there is one.
175
    """
176

177
    try:
×
178
        response.raise_for_status()
×
179

180
        return  # no error
×
181
    except HTTPError as http_error:
×
182
        exception = http_error
×
183

184
    # try to parse it as a Geo Engine error
185
    try:
×
186
        response_json = response.json()
×
187
    except Exception:  # pylint: disable=broad-except
×
188
        pass  # ignore errors, it seemed not to be JSON
×
189
    else:
190
        # if parsing was successful, raise the appropriate exception
191
        if "error" in response_json:
×
192
            raise GeoEngineException(response_json)
×
193

194
    # raise `HTTPError` if `GeoEngineException` or any other was not thrown
195
    raise exception
×
196

197

198
class MethodOnlyAvailableInGeoEnginePro(Exception):
1✔
199
    """
200
    Exception when trying to use a method that is only available in Geo Engine Pro
201
    """
202

203
    __message: str
1✔
204

205
    def __init__(self, message: str) -> None:
1✔
206
        super().__init__()
×
207

208
        self.__message = message
×
209

210
    def __str__(self) -> str:
1✔
211
        return f"Method is only available in Geo Engine Pro: {self.__message}"
×
212

213

214
class OGCXMLError(Exception):
1✔
215
    """
216
    Exception when an OGC XML error is returned
217
    """
218

219
    __xml: ET.Element
1✔
220

221
    def __init__(self, xml: bytearray) -> None:
1✔
222
        super().__init__()
1✔
223

224
        self.__xml = ET.fromstring(xml[1:])
1✔
225

226
    def __str__(self) -> str:
1✔
227
        service_exception = ""
1✔
228
        for e in self.__xml:
1✔
229
            if "ServiceException" in e.tag and e.text is not None:
1✔
230
                service_exception = e.text
1✔
231
                break
1✔
232

233
        return f"OGC API error: {service_exception}"
1✔
234

235
    @classmethod
1✔
236
    def is_ogc_error(cls, xml: bytearray) -> bool:
1✔
237
        return xml.startswith(b"\n<?xml")
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

© 2025 Coveralls, Inc