Coverage for gws-app/gws/base/ows/server/error.py: 59%
70 statements
« prev ^ index » next coverage.py v7.11.0, created at 2025-10-16 23:09 +0200
« prev ^ index » next coverage.py v7.11.0, created at 2025-10-16 23:09 +0200
1"""OWS-specific errors.
3Each error class corresponds to an OWS error code, as defined in OGC standards.
4"""
6import gws
7import gws.lib.xmlx as xmlx
8import gws.lib.image
9import gws.lib.mime
12class Error(gws.Error):
13 """OWS error."""
15 def __init__(self, *args):
16 super().__init__(*args)
17 self.code = self.__class__.__name__
18 self.locator = self.args[0] if len(self.args) > 0 else ''
19 self.message = self.args[1] if len(self.args) > 1 else ''
20 # NB assume it's the user's fault by default
21 self.status = _STATUS.get(self.code, 400)
23 def to_xml_response(self, xmlns='ows') -> gws.ContentResponse:
24 """Returns an XML response for this error.
26 Args:
27 xmlns: XML namespace to use (``ogc`` or ``ows``).
28 """
30 if xmlns == 'ows':
31 # OWS ExceptionReport, as per OGC 06-121r9, 8.5
32 ns = xmlx.namespace.require('ows11')
33 xml = xmlx.tag(
34 'ExceptionReport',
35 (
36 'Exception',
37 {'exceptionCode': self.code, 'locator': self.locator},
38 self.message,
39 ),
40 )
42 elif xmlns == 'ogc':
43 # OGC ServiceExceptionReport, as per OGC 06-042, H.2
44 ns = xmlx.namespace.require('ogc')
45 xml = xmlx.tag(
46 'ServiceExceptionReport',
47 (
48 'ServiceException',
49 {'code': self.code},
50 self.message,
51 ),
52 )
54 else:
55 raise gws.Error(f'invalid {xmlns=}')
57 return gws.ContentResponse(
58 status=self.status,
59 mime=gws.lib.mime.XML,
60 content=xml.to_string(
61 gws.XmlOptions(
62 defaultNamespace=ns,
63 withXmlDeclaration=True,
64 withNamespaceDeclarations=True,
65 )
66 ),
67 )
69 def to_image_response(self, mime='image/png') -> gws.ContentResponse:
70 """Returns an image response for this error.
72 Args:
73 mime: Image mime type.
74 """
76 return gws.ContentResponse(
77 status=self.status,
78 mime=mime,
79 content=gws.lib.image.error_pixel(mime),
80 )
83def from_exception(exc: Exception) -> Error:
84 """Convert an Exception to the OWS Error."""
86 if isinstance(exc, Error):
87 return exc
89 e = None
91 if isinstance(exc, gws.NotFoundError):
92 e = NotFound()
93 elif isinstance(exc, gws.ForbiddenError):
94 e = Forbidden()
95 elif isinstance(exc, gws.BadRequestError):
96 e = BadRequest()
98 if e:
99 gws.log.warning(f'OWS Exception: {e.code} cause={exc!r}')
100 else:
101 gws.log.exception()
102 e = NoApplicableCode('', 'Internal Server Error')
104 e.__cause__ = exc
105 return e
108# @formatter:off
110# out extensions
113class NotFound(Error): ...
116class Forbidden(Error): ...
119class BadRequest(Error): ...
122# OGC 06-121r9
123# Table 27 — Standard exception codes and meanings
126class InvalidParameterValue(Error): ...
129class InvalidUpdateSequence(Error): ...
132class MissingParameterValue(Error): ...
135class NoApplicableCode(Error): ...
138class OperationNotSupported(Error): ...
141class OptionNotSupported(Error): ...
144class VersionNegotiationFailed(Error): ...
147# OGC 06-042
148# Table E.1 — Service exception codes
151class CurrentUpdateSequence(Error): ...
154class InvalidCRS(Error): ...
157class InvalidDimensionValue(Error): ...
160class InvalidFormat(Error): ...
163class InvalidPoint(Error): ...
166class LayerNotDefined(Error): ...
169class LayerNotQueryable(Error): ...
172class MissingDimensionValue(Error): ...
175class StyleNotDefined(Error): ...
178# OGC 07-057r7
179# Table 20 — Exception codes for GetCapabilities operation
180# Table 23 — Exception codes for GetTile operation
183class PointIJOutOfRange(Error): ...
186class TileOutOfRange(Error): ...
189# OGC 09-025r1
190# Table 3 — WFS exception codes
193class CannotLockAllFeatures(Error): ...
196class DuplicateStoredQueryIdValue(Error): ...
199class DuplicateStoredQueryParameterName(Error): ...
202class FeaturesNotLocked(Error): ...
205class InvalidLockId(Error): ...
208class InvalidValue(Error): ...
211class LockHasExpired(Error): ...
214class OperationParsingFailed(Error): ...
217class OperationProcessingFailed(Error): ...
220class ResponseCacheExpired(Error): ...
223# OGC 06-121r9 8.6 HTTP STATUS codes for OGC Exceptions
225_STATUS = dict(
226 OperationNotSupported=501,
227 MissingParameterValue=400,
228 InvalidParameterValue=400,
229 VersionNegotiationFailed=400,
230 InvalidUpdateSequence=400,
231 OptionNotSupported=501,
232 NoApplicableCode=500,
233 NotFound=404,
234 Forbidden=403,
235 BadRequest=400,
236)