7from json
import JSONDecodeError
8from urllib.parse
import urlparse
9from httpx
import HTTPError, HTTPStatusError
11 SearxXPathSyntaxException,
12 SearxEngineXPathException,
13 SearxEngineAPIException,
14 SearxEngineAccessDeniedException,
16from searx
import searx_parent_dir, settings
20errors_per_engines: dict[str, t.Any] = {}
22LogParametersType = tuple[str, ...]
33 exception_classname: str,
35 log_parameters: LogParametersType,
48 if not isinstance(o, ErrorContext):
54 and self.
code == o.code
76 return "ErrorContext({!r}, {!r}, {!r}, {!r}, {!r}, {!r}) {!r}".format(
88 errors_for_engine = errors_per_engines.setdefault(engine_name, {})
89 errors_for_engine[error_context] = errors_for_engine.get(error_context, 0) + 1
90 engines[engine_name].logger.warning(
'%s', str(error_context))
94 for trace
in reversed(traces):
95 split_filename: list[str] = trace.filename.split(
'/')
96 if '/'.join(split_filename[-3:-1]) ==
'searx/engines':
98 if '/'.join(split_filename[-4:-1]) ==
'searx/search/processors':
104 url = exc.request.url
105 if url
is None and exc.response
is not None:
106 url = exc.response.url
107 return urlparse(url).netloc
112) -> tuple[str |
None, str |
None, str |
None]:
117 if hasattr(exc,
'_request')
and exc._request
is not None:
120 url = exc.request.url
121 if url
is None and hasattr(exc,
'response')
and exc.response
is not None:
122 url = exc.response.url
125 if isinstance(exc, HTTPStatusError):
126 status_code = str(exc.response.status_code)
127 reason = exc.response.reason_phrase
128 return (status_code, reason, hostname)
132 if isinstance(exc, JSONDecodeError):
134 if isinstance(exc, TypeError):
136 if isinstance(exc, ValueError)
and 'lxml' in filename:
138 if isinstance(exc, HTTPError):
140 if isinstance(exc, SearxXPathSyntaxException):
141 return (exc.xpath_str, exc.message)
142 if isinstance(exc, SearxEngineXPathException):
143 return (exc.xpath_str, exc.message)
144 if isinstance(exc, SearxEngineAPIException):
145 return (str(exc.args[0]),)
146 if isinstance(exc, SearxEngineAccessDeniedException):
147 return (exc.message,)
152 exc_class = exc.__class__
153 exc_name = exc_class.__qualname__
154 exc_module = exc_class.__module__
155 if exc_module
is None or exc_module == str.__class__.__module__:
157 return exc_module +
'.' + exc_name
161 framerecords, exception_classname, log_message, log_parameters: LogParametersType, secondary: bool
164 filename = searx_frame.filename
165 if filename.startswith(searx_parent_dir):
166 filename = filename[len(searx_parent_dir) + 1 :]
167 function = searx_frame.function
168 line_no = searx_frame.lineno
169 code = searx_frame.code_context[0].strip()
171 return ErrorContext(filename, function, line_no, code, exception_classname, log_message, log_parameters, secondary)
174def count_exception(engine_name: str, exc: BaseException, secondary: bool =
False) ->
None:
175 if not settings[
'general'][
'enable_metrics']:
177 framerecords = inspect.trace()
181 error_context =
get_error_context(framerecords, exception_classname,
None, log_parameters, secondary)
190 log_parameters: LogParametersType |
None =
None,
191 secondary: bool =
False,
193 if not settings[
'general'][
'enable_metrics']:
195 framerecords = list(reversed(inspect.stack()[1:]))
197 error_context =
get_error_context(framerecords,
None, log_message, log_parameters
or (), secondary)
LogParametersType log_parameters
__init__(self, str filename, str function, int line_no, str code, str exception_classname, str log_message, LogParametersType log_parameters, bool secondary)
ErrorContext get_error_context(framerecords, exception_classname, log_message, LogParametersType log_parameters, bool secondary)
None count_error(str engine_name, str log_message, LogParametersType|None log_parameters=None, bool secondary=False)
str|None get_hostname(HTTPError exc)
tuple[str|None, str|None, str|None] get_request_exception_messages(HTTPError exc)
None add_error_context(str engine_name, ErrorContext error_context)
None count_exception(str engine_name, BaseException exc, bool secondary=False)
str get_exception_classname(BaseException exc)
tuple[str,...] get_messages(exc, filename)