Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/looker_sdk/error.py: 49%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

67 statements  

1# The MIT License (MIT) 

2# 

3# Copyright (c) 2019 Looker Data Sciences, Inc. 

4# 

5# Permission is hereby granted, free of charge, to any person obtaining a copy 

6# of this software and associated documentation files (the "Software"), to deal 

7# in the Software without restriction, including without limitation the rights 

8# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 

9# copies of the Software, and to permit persons to whom the Software is 

10# furnished to do so, subject to the following conditions: 

11# 

12# The above copyright notice and this permission notice shall be included in 

13# all copies or substantial portions of the Software. 

14# 

15# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 

16# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 

17# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 

18# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 

19# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 

20# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 

21# THE SOFTWARE. 

22 

23import attr 

24from typing import cast, Dict, Optional, Sequence, Tuple 

25import requests 

26import json 

27import re 

28 

29"""API error class 

30""" 

31 

32 

33@attr.s(auto_attribs=True, kw_only=True) 

34class ErrorDetail: 

35 """Error detail: 

36 documentation_url: documentation link 

37 field: field with error 

38 code: error code 

39 message: error info message 

40 error_doc_url: URL that may point to additional useful information 

41 error_doc: Markdown doc that may contain additional useful information 

42 """ 

43 

44 documentation_url: str 

45 field: Optional[str] = "" 

46 code: Optional[str] = "" 

47 message: Optional[str] = "" 

48 error_doc_url: str = "" 

49 error_doc: str = "" 

50 

51 def __str__(self): 

52 return f""" 

53 ***** 

54 documentation_url: {self.documentation_url} 

55 field: {self.field} 

56 code: {self.code} 

57 message: {self.message} 

58 error_doc_url: {self.error_doc_url} 

59 """ 

60 

61 

62@attr.s(auto_attribs=True) 

63class SDKError(Exception): 

64 """API error class: 

65 message: main error info message 

66 errors: array of error details 

67 documentation_url: documentation link 

68 error_doc_url: URL that may point to additional useful information 

69 error_doc: Markdown doc that may contain additional useful information 

70 """ 

71 

72 message: str 

73 errors: Sequence[ErrorDetail] = attr.ib(default=[], kw_only=True) 

74 documentation_url: str = attr.ib(default="", kw_only=True) 

75 error_doc_url: str = "" 

76 error_doc: str = "" 

77 

78 def __str__(self): 

79 sep = "****\n" 

80 return f""" 

81 message: {self.message} 

82 documentation_url: {self.documentation_url} 

83 error_doc_url: {self.error_doc_url} 

84 error details: 

85 {sep.join(str(error_details) for error_details in self.errors)} 

86 """ 

87 

88 

89"""Error Doc Helper class 

90""" 

91 

92 

93@attr.s(auto_attribs=True, kw_only=True) 

94class ErrorDocHelper: 

95 """Error Doc Helper: 

96 error_doc_url: link 

97 """ 

98 

99 ERROR_CODES_URL: str = "https://static-a.cdn.looker.app/errorcodes/" 

100 lookup_dict: Dict[str, Dict[str, str]] = {} 

101 RE_PATTERN: str = ( 

102 r'(https://docs\.looker\.com/r/err/|https://cloud\.google\.com/looker/docs/r/err/)(.*)/(\d{3})(.*)' 

103 ) 

104 pattern = re.compile(RE_PATTERN, flags=re.IGNORECASE) 

105 

106 def get_index(self, url: str = ERROR_CODES_URL) -> None: 

107 r = requests.get(f"{url}index.json") 

108 self.lookup_dict = json.loads(r.text) 

109 

110 def lookup( 

111 self, url: str = ERROR_CODES_URL, code: str = "", path: str = "" 

112 ) -> Tuple[str, str]: 

113 if len(self.lookup_dict) == 0: 

114 self.get_index(url=url) 

115 

116 error_doc_url: str = "" 

117 error_doc: str = "" 

118 if path: 

119 try: 

120 error_doc_url = self.lookup_dict[f"{code}{path}"]["url"] 

121 except KeyError: 

122 error_doc = f"### No documentation found for {code}{path}" 

123 if not error_doc_url: 

124 try: 

125 error_doc_url = self.lookup_dict[code]["url"] 

126 except KeyError: 

127 if not error_doc: 

128 error_doc = f"### No documentation found for {code}" 

129 

130 if error_doc_url: 

131 r = requests.get(f"{self.ERROR_CODES_URL}{error_doc_url}") 

132 error_doc = r.text 

133 

134 return (f"{self.ERROR_CODES_URL}{error_doc_url}", error_doc) 

135 

136 def parse_and_lookup( 

137 self, error_url: str, url: str = ERROR_CODES_URL 

138 ) -> Tuple[str, str]: 

139 m = re.search(self.RE_PATTERN, error_url) 

140 if not m: 

141 return ("", "") 

142 

143 code: str = cast(Tuple[str, str, str, str], m.groups())[2] 

144 path: str = cast(Tuple[str, str, str, str], m.groups())[3] 

145 try: 

146 return self.lookup(url=url, code=code, path=path) 

147 except requests.exceptions.RequestException: 

148 return ("", "")