{"id":"163741737ff66ad8","repo":"square/okhttp","slug":"unexpected-code-163741","errorCode":null,"errorMessage":"Unexpected code ","messagePattern":"Unexpected code ","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"samples/guide/src/main/java/okhttp3/recipes/Progress.java","lineNumber":72,"sourceCode":"\n          if (contentLength != -1) {\n            System.out.format(\"%d%% done\\n\", (100 * bytesRead) / contentLength);\n          }\n        }\n      }\n    };\n\n    OkHttpClient client = new OkHttpClient.Builder()\n        .addNetworkInterceptor(chain -> {\n          Response originalResponse = chain.proceed(chain.request());\n          return originalResponse.newBuilder()\n              .body(new ProgressResponseBody(originalResponse.body(), progressListener))\n              .build();\n        })\n        .build();\n\n    try (Response response = client.newCall(request).execute()) {\n      if (!response.isSuccessful()) throw new IOException(\"Unexpected code \" + response);\n\n      System.out.println(response.body().string());\n    }\n  }\n\n  public static void main(String... args) throws Exception {\n    new Progress().run();\n  }\n\n  private static class ProgressResponseBody extends ResponseBody {\n\n    private final ResponseBody responseBody;\n    private final ProgressListener progressListener;\n    private BufferedSource bufferedSource;\n\n    ProgressResponseBody(ResponseBody responseBody, ProgressListener progressListener) {\n      this.responseBody = responseBody;\n      this.progressListener = progressListener;","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/square/okhttp/blob/4fc083138014aba3d0078f5c26d1ce84815fa984/samples/guide/src/main/java/okhttp3/recipes/Progress.java#L54-L90","documentation":"Recipe-level guard inside a client that installs a network interceptor wrapping the ResponseBody in a ProgressResponseBody (ForwardingSource that counts bytes read). After the wrapped response is returned, response.isSuccessful() is checked; non-2xx throws java.io.IOException(\"Unexpected code \" + response). The progress wrapping does not change the status, so this is a normal HTTP-error guard layered over a progress-tracking body.","triggerScenarios":"GET https://publicobject.com/helloworld.txt with the progress interceptor. Fires on any non-2xx (404, 503, etc.). Note the ProgressResponseBody wraps whatever body the server returns, so for an error response the progress listener will report the error body's bytes before this line throws.","commonSituations":"Origin returning 5xx during maintenance; expecting the progress listener to only fire for successful bodies (it fires for error bodies too); host redirect/parked page.","solutions":["Inspect response.code() and the progress listener's reported contentLength.","Do not assume bytesRead corresponds to the successful payload — guard for error responses.","Verify the URL still serves the expected plaintext."],"exampleFix":"// before\ntry (Response response = client.newCall(request).execute()) {\n  if (!response.isSuccessful()) throw new IOException(\"Unexpected code \" + response);\n  ...\n}\n\n// after\ntry (Response response = client.newCall(request).execute()) {\n  if (!response.isSuccessful()) {\n    // the progress listener has already counted the error body bytes\n    throw new IOException(\"HTTP \" + response.code() + \" for \" + request.url());\n  }\n  ...\n}","handlingStrategy":"validation","validationCode":"// The ProgressResponseBody wraps error bodies too; account for that in the listener\n@Override public void update(long bytesRead, long contentLength, boolean done) {\n  // only treat as a successful download if the caller later confirms response.isSuccessful()\n  if (contentLength == -1) { /* unknown size; likely an error or chunked body */ }\n  ...\n}","typeGuard":null,"tryCatchPattern":"try (Response response = client.newCall(request).execute()) {\n  if (!response.isSuccessful()) {\n    // the progress listener has already counted the error body's bytes\n    throw new HttpException(response.code(), response.message());\n  }\n  // only now treat progress numbers as authoritative for the successful payload\n}","preventionTips":["Do not assume progress bytes correspond to a successful payload — error bodies are wrapped too.","Log response.code() alongside the progress listener to correlate partial reads with errors.","Verify the URL still serves the expected content type and length.","Handle contentLength == -1 (unknown / chunked) gracefully."],"tags":["okhttp","http-status","progress","interceptor","java"],"analyzedSha":"4fc083138014aba3d0078f5c26d1ce84815fa984","analyzedAt":"2026-08-04T19:09:04.639Z","schemaVersion":2}