{"id":"985433b5d3330969","repo":"redis/redis-py","slug":"http-status-for-url","errorCode":null,"errorMessage":"HTTP {status} for {url}","messagePattern":"HTTP (.+?) for (.+?)","errorType":"http","errorClass":"HttpError","httpStatus":null,"severity":"error","filePath":"redis/http/http_client.py","lineNumber":347,"sourceCode":"        path: str,\n        params: Optional[\n            Mapping[str, Union[None, str, int, float, bool, list, tuple]]\n        ] = None,\n        headers: Optional[Mapping[str, str]] = None,\n        timeout: Optional[float] = None,\n        body: Optional[Union[bytes, str]] = None,\n        expect_json: bool = True,\n    ) -> Union[HttpResponse, Any]:\n        resp = self.request(\n            method=method,\n            path=path,\n            params=params,\n            headers=headers,\n            body=body,\n            timeout=timeout,\n        )\n        if not (200 <= resp.status < 400):\n            raise HttpError(resp.status, resp.url, resp.text())\n        if expect_json:\n            return resp.json()\n        return resp\n\n    def _prepare_body(\n        self, json_body: Optional[Any] = None, data: Optional[Union[bytes, str]] = None\n    ) -> Optional[Union[bytes, str]]:\n        if json_body is not None and data is not None:\n            raise ValueError(\"Provide either json_body or data, not both.\")\n        if json_body is not None:\n            return json.dumps(json_body, ensure_ascii=False, separators=(\",\", \":\"))\n        return data\n\n    def _build_url(\n        self,\n        path: str,\n        params: Optional[\n            Mapping[str, Union[None, str, int, float, bool, list, tuple]]","sourceCodeStart":329,"sourceCodeEnd":365,"githubUrl":"https://github.com/redis/redis-py/blob/da03cdc7e8731092b13e395605c3c1fb2de25de1/redis/http/http_client.py#L329-L365","documentation":"Raised as redis.http.http_client.HttpError by HttpClient._json_call (redis/http/http_client.py:347) whenever an HTTP response has a status outside the 200–399 success range, after all configured retries are exhausted. The exception carries .status, .url, and the response body text so the caller can branch on the status code. RETRY_STATUS_CODES {429,500,502,503,504} are retried automatically before this is raised.","triggerScenarios":"Any HttpClient .get/.post/.put/.patch/.delete (or _json_call) call whose final response status is >= 400: 401/403 auth failure, 404 not found, 400 bad request, or a non-retryable 5xx after retries give up.","commonSituations":"Expired/invalid auth token (401/403); wrong endpoint or path (404); malformed request body (400); upstream outage returning a non-retryable error; TLS/mTLS misconfiguration surfacing as a 4xx from a gateway.","solutions":["Catch HttpError and branch on exc.status: refresh credentials on 401, fix the path on 404, surface 4xx as caller errors.","For 5xx, increase Retry.retries / widen _should_retry_status or retry at the call site with backoff.","Log exc.url and exc.message (and exc.text via resp) to pinpoint the failing endpoint.","Verify auth headers, base_url, and mTLS cert/key paths are correct for the target service."],"exampleFix":"// before\nresp = client.post('/v1/token', json_body=payload)  # HttpError on 4xx/5xx\n\n// after\nfrom redis.http.http_client import HttpError\ntry:\n    resp = client.post('/v1/token', json_body=payload)\nexcept HttpError as e:\n    if e.status in (401, 403):\n        refresh_credentials()\n        raise\n    raise","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"from redis.http.http_client import HttpError\ndef is_http_error(e) -> bool:\n    return isinstance(e, HttpError)","tryCatchPattern":"from redis.http.http_client import HttpError\ntry:\n    resp = client.post('/v1/token', json_body=payload)\nexcept HttpError as e:\n    if e.status in (401, 403):\n        refresh_credentials()  # then optionally retry\n    if 500 <= e.status < 600 and e.status in {500, 502, 503, 504}:\n        # already retried by client; surface as transient\n        raise TransientUpstream(e)\n    raise","preventionTips":["Branch on exc.status: 401/403 -> refresh creds, 404 -> fix path, 4xx -> caller error.","Tune Retry.retries and the retryable status set for transient 5xx.","Log exc.url and exc.message (and resp body) to pinpoint the failing endpoint.","Validate auth headers and mTLS paths before relying on the endpoint."],"tags":["http","httpclient","auth","network","retry"],"analyzedSha":"da03cdc7e8731092b13e395605c3c1fb2de25de1","analyzedAt":"2026-08-04T20:26:47.563Z","schemaVersion":2}