diff --git a/src/supergood/api.py b/src/supergood/api.py index dda1ab6..a7d37e8 100644 --- a/src/supergood/api.py +++ b/src/supergood/api.py @@ -19,6 +19,7 @@ def __init__( self.error_sink_url = None self.config_pull_url = None self.telemetry_post_url = None + self.log = None def set_logger(self, logger): self.log = logger @@ -39,7 +40,11 @@ def post_telemetry(self, payload): if response.status_code == 401: raise Exception(ERRORS["UNAUTHORIZED"]) if response.status_code != 200 and response.status_code != 201: - raise Exception(ERRORS["POSTING_TELEMETRY"]) + if self.log: + self.log.warning( + f"[Supergood] Got non-2xx status code {response.status_code} on telemetry post" + ) + return None return response.json() # Remote config fetching @@ -53,7 +58,11 @@ def get_config(self): if response.status_code == 401: raise Exception(ERRORS["UNAUTHORIZED"]) elif response.status_code != 200: - raise Exception(ERRORS["FETCHING_CONFIG"]) + if self.log: + self.log.warning( + f"[Supergood] Got non-2xx status code {response.status_code} on config get" + ) + return None return response.json() # Event posting @@ -69,7 +78,11 @@ def post_events(self, payload): if response.status_code == 401: raise Exception(ERRORS["UNAUTHORIZED"]) if response.status_code != 200 and response.status_code != 201: - raise Exception(ERRORS["POSTING_EVENTS"]) + if self.log: + self.log.warning( + f"[Supergood] Got non-2xx status code {response.status_code} on event post" + ) + return None return response.json() # Error posting diff --git a/src/supergood/client.py b/src/supergood/client.py index 4093d28..ad8109b 100644 --- a/src/supergood/client.py +++ b/src/supergood/client.py @@ -314,7 +314,9 @@ def kill(self) -> None: def _get_config(self) -> None: try: raw_config = self.api.get_config() - self.remote_config = parse_remote_config_json(raw_config) + if raw_config is not None: + # non-exception erroring / warning is handled by the API + self.remote_config = parse_remote_config_json(raw_config) except Exception: if self.remote_config: self.log.warning("Failed to update remote config") @@ -448,6 +450,8 @@ def sync_flush_cache(self, data) -> None: try: if self.base_config["forceRedactAll"]: redact_all(data) + elif self.base_config["redactByDefault"]: + redact_all(data, self.remote_config, by_default=True) elif self.base_config["useRemoteConfig"]: to_delete = redact_values( data, diff --git a/src/supergood/vendors/aiohttp.py b/src/supergood/vendors/aiohttp.py index f2bc09c..5d3c407 100644 --- a/src/supergood/vendors/aiohttp.py +++ b/src/supergood/vendors/aiohttp.py @@ -22,11 +22,13 @@ async def _wrap_request(clientSession, method, url, *args, **kwargs): return response async def _wrap_read(clientResponse): - request_id = getattr(clientResponse, REQUEST_ID_KEY) + request_id = getattr(clientResponse, REQUEST_ID_KEY, None) + response_body = await _original_read(clientResponse) + if request_id is None: + return response_body response_headers = clientResponse.headers response_status = clientResponse.status response_status_text = clientResponse.reason - response_body = await _original_read(clientResponse) cache_response( request_id, diff --git a/src/supergood/vendors/http.py b/src/supergood/vendors/http.py index 6f85713..1271067 100644 --- a/src/supergood/vendors/http.py +++ b/src/supergood/vendors/http.py @@ -15,7 +15,9 @@ def patch(cache_request, cache_response): def _wrap_read(httpResponse, amt=None): response_object = httpResponse response_body = _original_read(httpResponse, amt) - request_id = getattr(response_object, REQUEST_ID_KEY) + request_id = getattr(response_object, REQUEST_ID_KEY, None) + if request_id is None: + return response_body response_headers = _original_getheaders(httpResponse) response_status = response_object.status response_status_text = response_object.reason diff --git a/src/supergood/vendors/httpx.py b/src/supergood/vendors/httpx.py index 8e1a4b4..4f0e3b1 100644 --- a/src/supergood/vendors/httpx.py +++ b/src/supergood/vendors/httpx.py @@ -51,7 +51,9 @@ async def _wrap_handle_async_request( async def _wrap_response_aread(response: httpx.Response): response_body = await _original_response_aread(response) - request_id = getattr(response, REQUEST_ID_KEY) + request_id = getattr(response, REQUEST_ID_KEY, None) + if request_id is None: + return response_body status_text = response.extensions.get("reason_phrase", None) if status_text: status_text = status_text.decode("utf-8") @@ -66,7 +68,9 @@ async def _wrap_response_aread(response: httpx.Response): def _wrap_response_read(response: httpx.Response): response_body = _original_response_read(response) - request_id = getattr(response, REQUEST_ID_KEY) + request_id = getattr(response, REQUEST_ID_KEY, None) + if request_id is None: + return response_body status_text = response.extensions.get("reason_phrase", None) if status_text: status_text = status_text.decode("utf-8") @@ -80,7 +84,7 @@ def _wrap_response_read(response: httpx.Response): return response_body def _wrap_iter_lines(response: httpx.Response): - request_id = getattr(response, REQUEST_ID_KEY) + request_id = getattr(response, REQUEST_ID_KEY, None) status_text = response.extensions.get("reason_phrase", None) if status_text: status_text = status_text.decode("utf-8") @@ -89,17 +93,19 @@ def _wrap_iter_lines(response: httpx.Response): if line: response_parts.append(line) yield line - response_body = "\n".join(response_parts) - cache_response( - request_id, - response_body, - response.headers, - response.status_code, - status_text, - ) + if request_id is not None: + # This only happens if we successfully cached the request + response_body = "\n".join(response_parts) + cache_response( + request_id, + response_body, + response.headers, + response.status_code, + status_text, + ) async def _wrap_aiter_lines(response: httpx.Response): - request_id = getattr(response, REQUEST_ID_KEY) + request_id = getattr(response, REQUEST_ID_KEY, None) status_text = response.extensions.get("reason_phrase", None) if status_text: status_text = status_text.decode("utf-8") @@ -108,14 +114,15 @@ async def _wrap_aiter_lines(response: httpx.Response): if line: response_parts.append(line) yield line - response_body = "\n".join(response_parts) - cache_response( - request_id, - response_body, - response.headers, - response.status_code, - status_text, - ) + if request_id is not None: + response_body = "\n".join(response_parts) + cache_response( + request_id, + response_body, + response.headers, + response.status_code, + status_text, + ) def _parse_sse(chunk: str): data = [] @@ -155,7 +162,7 @@ def _parse_sse(chunk: str): return None def _wrap_iter_bytes(response: httpx.Response, chunk_size: Optional[int] = None): - request_id = getattr(response, REQUEST_ID_KEY) + request_id = getattr(response, REQUEST_ID_KEY, None) status_text = response.extensions.get("reason_phrase", None) if status_text: status_text = status_text.decode("utf-8") @@ -176,25 +183,27 @@ def _wrap_iter_bytes(response: httpx.Response, chunk_size: Optional[int] = None) response_chunks.append(decoded) data = b"" yield chunk - if len(data): - # must have been an invalid chunk, append it anyway - response_chunks.append(data) - try: - response_body = json.dumps(response_chunks, cls=DataclassesJSONEncoder) - except Exception: - response_body = str(response_chunks) - cache_response( - request_id, - response_body, - response.headers, - response.status_code, - status_text, - ) + if request_id is not None: + # Only happens if the request was successfully cached + if len(data): + # must have been an invalid chunk, append it anyway + response_chunks.append(data) + try: + response_body = json.dumps(response_chunks, cls=DataclassesJSONEncoder) + except Exception: + response_body = str(response_chunks) + cache_response( + request_id, + response_body, + response.headers, + response.status_code, + status_text, + ) async def _wrap_aiter_bytes( response: httpx.Response, chunk_size: Optional[int] = None ): - request_id = getattr(response, REQUEST_ID_KEY) + request_id = getattr(response, REQUEST_ID_KEY, None) status_text = response.extensions.get("reason_phrase", None) if status_text: status_text = status_text.decode("utf-8") @@ -215,20 +224,21 @@ async def _wrap_aiter_bytes( response_chunks.append(decoded) data = b"" yield chunk - if len(data): - # must have been an invalid chunk, append it anyway - response_chunks.append(data) - try: - response_body = json.dumps(response_chunks, cls=DataclassesJSONEncoder) - except Exception: - response_body = str(response_chunks) - cache_response( - request_id, - response_body, - response.headers, - response.status_code, - status_text, - ) + if request_id is not None: + if len(data): + # must have been an invalid chunk, append it anyway + response_chunks.append(data) + try: + response_body = json.dumps(response_chunks, cls=DataclassesJSONEncoder) + except Exception: + response_body = str(response_chunks) + cache_response( + request_id, + response_body, + response.headers, + response.status_code, + status_text, + ) httpx.HTTPTransport.handle_request = _wrap_handle_request httpx.Response.read = _wrap_response_read diff --git a/src/supergood/vendors/urllib3.py b/src/supergood/vendors/urllib3.py index ec66d44..8c5a790 100644 --- a/src/supergood/vendors/urllib3.py +++ b/src/supergood/vendors/urllib3.py @@ -23,16 +23,17 @@ def _wrap_read_chunked(urllib3HttpResponse, amt=None, decode_content=None): response_bytes.append(line) yield line - request_id = getattr(response_object, REQUEST_ID_KEY) - response_headers = _original_getheaders(response_object) - response_body = b"".join(response_bytes) - cache_response( - request_id=request_id, - response_body=response_body, - response_headers=response_headers, - response_status=response_object.status, - response_status_text=response_object.reason, - ) + request_id = getattr(response_object, REQUEST_ID_KEY, None) + if request_id is not None: + response_headers = _original_getheaders(response_object) + response_body = b"".join(response_bytes) + cache_response( + request_id=request_id, + response_body=response_body, + response_headers=response_headers, + response_status=response_object.status, + response_status_text=response_object.reason, + ) def _wrap_request(http_connection, method, url, body=None, headers=None, **kwargs): request_id = str(uuid4())