Coverage for gws-app/gws/base/ows/server/error.py: 0%

68 statements  

« prev     ^ index     » next       coverage.py v7.8.0, created at 2025-04-17 01:37 +0200

1"""OWS-specific errors. 

2 

3Each error class corresponds to an OWS error code, as defined in OGC standards. 

4""" 

5 

6import gws 

7import gws.lib.xmlx 

8import gws.lib.image 

9import gws.lib.mime 

10 

11 

12class Error(gws.Error): 

13 """OWS error.""" 

14 

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) 

22 

23 def to_xml_response(self, xmlns='ows') -> gws.ContentResponse: 

24 """Returns an XML response for this error. 

25 

26 Args: 

27 xmlns: XML namespace to use (``ogc`` or ``ows``). 

28 """ 

29 

30 if xmlns == 'ows': 

31 # OWS ExceptionReport, as per OGC 06-121r9, 8.5 

32 xml = gws.lib.xmlx.tag( 

33 'ExceptionReport', {'xmlns': 'ows'}, 

34 ('Exception', {'exceptionCode': self.code, 'locator': self.locator}, self.message) 

35 ) 

36 

37 elif xmlns == 'ogc': 

38 # OGC ServiceExceptionReport, as per OGC 06-042, H.2 

39 xml = gws.lib.xmlx.tag( 

40 'ServiceExceptionReport', {'xmlns': 'ogc'}, 

41 ('ServiceException', {'exceptionCode': self.code, 'locator': self.locator}, self.message) 

42 ) 

43 

44 else: 

45 raise gws.Error(f'invalid {xmlns=}') 

46 

47 return gws.ContentResponse( 

48 status=self.status, 

49 mime=gws.lib.mime.XML, 

50 content=xml.to_string( 

51 with_namespace_declarations=True, 

52 with_schema_locations=False, 

53 ) 

54 ) 

55 

56 def to_image_response(self, mime='image/png') -> gws.ContentResponse: 

57 """Returns an image response for this error. 

58 

59 Args: 

60 mime: Image mime type. 

61 """ 

62 

63 return gws.ContentResponse( 

64 status=self.status, 

65 mime=mime, 

66 content=gws.lib.image.error_pixel(mime), 

67 ) 

68 

69 

70def from_exception(exc: Exception) -> Error: 

71 """Convert an Exception to the OWS Error.""" 

72 

73 if isinstance(exc, Error): 

74 return exc 

75 

76 e = None 

77 

78 if isinstance(exc, gws.NotFoundError): 

79 e = NotFound() 

80 elif isinstance(exc, gws.ForbiddenError): 

81 e = Forbidden() 

82 elif isinstance(exc, gws.BadRequestError): 

83 e = BadRequest() 

84 

85 if e: 

86 gws.log.warning(f'OWS Exception: {e.code} cause={exc!r}') 

87 else: 

88 gws.log.exception() 

89 e = NoApplicableCode('', 'Internal Server Error') 

90 

91 e.__cause__ = exc 

92 return e 

93 

94 

95# @formatter:off 

96 

97# out extensions 

98 

99class NotFound(Error): ... 

100class Forbidden(Error): ... 

101class BadRequest(Error): ... 

102 

103# OGC 06-121r9 

104# Table 27 — Standard exception codes and meanings 

105 

106class InvalidParameterValue(Error): ... 

107class InvalidUpdateSequence(Error): ... 

108class MissingParameterValue(Error): ... 

109class NoApplicableCode(Error): ... 

110class OperationNotSupported(Error): ... 

111class OptionNotSupported(Error): ... 

112class VersionNegotiationFailed(Error): ... 

113 

114# OGC 06-042 

115# Table E.1 — Service exception codes 

116 

117class CurrentUpdateSequence(Error): ... 

118class InvalidCRS(Error): ... 

119class InvalidDimensionValue(Error): ... 

120class InvalidFormat(Error): ... 

121class InvalidPoint(Error): ... 

122class LayerNotDefined(Error): ... 

123class LayerNotQueryable(Error): ... 

124class MissingDimensionValue(Error): ... 

125class StyleNotDefined(Error): ... 

126 

127# OGC 07-057r7 

128# Table 20 — Exception codes for GetCapabilities operation 

129# Table 23 — Exception codes for GetTile operation 

130 

131class PointIJOutOfRange(Error): ... 

132class TileOutOfRange(Error): ... 

133 

134# OGC 09-025r1 

135# Table 3 — WFS exception codes 

136 

137class CannotLockAllFeatures(Error): ... 

138class DuplicateStoredQueryIdValue(Error): ... 

139class DuplicateStoredQueryParameterName(Error): ... 

140class FeaturesNotLocked(Error): ... 

141class InvalidLockId(Error): ... 

142class InvalidValue(Error): ... 

143class LockHasExpired(Error): ... 

144class OperationParsingFailed(Error): ... 

145class OperationProcessingFailed(Error): ... 

146class ResponseCacheExpired(Error): ... 

147 

148# OGC 06-121r9 8.6 HTTP STATUS codes for OGC Exceptions 

149 

150_STATUS = dict( 

151 OperationNotSupported=501, 

152 MissingParameterValue=400, 

153 InvalidParameterValue=400, 

154 VersionNegotiationFailed=400, 

155 InvalidUpdateSequence=400, 

156 OptionNotSupported=501, 

157 NoApplicableCode=500, 

158 

159 NotFound=404, 

160 Forbidden=403, 

161 BadRequest=400, 

162 

163)