{"record":{"id":"9ea0f80a869dfcad","repo":"pockethub/PocketHub","slug":"unexpected-response-code","errorCode":null,"errorMessage":"Unexpected response code: ","messagePattern":"Unexpected response code: ","errorType":"http","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"app/src/main/java/com/github/pockethub/android/util/HttpImageGetter.java","lineNumber":338,"sourceCode":"            }\n        } catch (Exception e) {\n            // Ignore and attempt request over regular HTTP request\n        }\n\n        try {\n            String logMessage = \"Loading image: \" + source;\n            Log.d(getClass().getSimpleName(), logMessage);\n            Bugsnag.leaveBreadcrumb(logMessage);\n\n            Request request = new Request.Builder()\n                    .get()\n                    .url(source)\n                    .build();\n\n            Response response = okHttpClient.newCall(request).execute();\n\n            if (!response.isSuccessful()) {\n                throw new IOException(\"Unexpected response code: \" + response.code());\n            }\n\n            Bitmap bitmap = BitmapFactory.decodeStream(response.body().byteStream());\n\n            if (bitmap == null) {\n                return loading.getDrawable(source);\n            }\n\n            BitmapDrawable drawable = new BitmapDrawable( context.getResources(), bitmap);\n            drawable.setBounds(0, 0, bitmap.getWidth(), bitmap.getHeight());\n            return drawable;\n        } catch (IOException e) {\n            Log.e(getClass().getSimpleName(), \"Error loading image\", e);\n            Bugsnag.notify(e);\n            return loading.getDrawable(source);\n        }\n    }\n","sourceCodeStart":320,"sourceCodeEnd":356,"githubUrl":"https://github.com/pockethub/PocketHub/blob/8228cb8f7197a7c2227e67ee48a2c8dc843fb553/app/src/main/java/com/github/pockethub/android/util/HttpImageGetter.java#L320-L356","documentation":"HttpImageGetter.getDrawable() downloads an image over HTTP with OkHttp and requires a successful (2xx) response before decoding the bitmap. On any non-2xx status it throws IOException(\"Unexpected response code: <code>\"). The code's actual HTTP status is appended at runtime.","triggerScenarios":"An <img> src in rendered Markdown resolves to a URL returning 404 (image deleted), 403 (hotlink protection / auth required), 401, or 5xx; redirects exhausted; rate limiting (429).","commonSituations":"Deleted GitHub user avatar or gist image; private image requiring auth headers; camo/proxy misconfiguration; CDN outage returning 5xx.","solutions":["Verify the image URL is reachable and returns 200 (curl -I).","Use the placeholder/loading drawable fallback so a failed load degrades gracefully.","Check auth headers are attached when loading private/authenticated images.","Implement retry with backoff for 429/5xx, and cache previously loaded bitmaps."],"exampleFix":"// before\nthrow new IOException(\"Unexpected response code: \" + response.code());\n// after\nif (!response.isSuccessful()) {\n    Log.w(TAG, \"Image fetch failed: \" + response.code());\n    return loading.getDrawable(source);\n}","handlingStrategy":"fallback","validationCode":"// HEAD-check the URL before fetching:\n// HttpURLConnection(url).requestMethod = \"HEAD\"; responseCode == 200","typeGuard":null,"tryCatchPattern":"try {\n    val d = httpImageGetter.getDrawable(source)\n} catch (e: IOException) {\n    loading.getDrawable(source) // placeholder fallback\n}","preventionTips":["Attach auth headers for private images","Cache previously loaded bitmaps","Retry 429/5xx with backoff","Show placeholder instead of crashing on 404/403"],"tags":["http","okhttp","image-loading","network"],"backgroundTag":"http-error-response","analyzedSha":"8228cb8f7197a7c2227e67ee48a2c8dc843fb553","analyzedAt":"2026-09-11T10:16:17.606Z","contentChangedAt":"2026-09-11T10:16:17.606Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}