{"record":{"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/91a8b34c6f44bd28c421364f8edadc9f324dddd9/samples/guide/src/main/java/okhttp3/recipes/Progress.java#L54-L90","documentation":"Thrown in the Progress recipe: `if (!response.isSuccessful()) throw new IOException(\"Unexpected code \" + response)`. A network interceptor wraps the response body in a ProgressResponseBody that reports bytes-read to a listener. The guard fires if the underlying server response is non-2xx. Note the progress body is still installed even on error responses, so the listener will fire for the error body bytes too.","triggerScenarios":"GET https://publicobject.com/helloworld.txt returns 404/403/5xx; the ProgressResponseBody wraps whatever body the server returned (possibly an error page), so the listener reports bytes for the error body and then this line throws.","commonSituations":"Sample host removed helloworld.txt; the progress numbers look wrong because they are measuring an HTML error page rather than the expected file; network interceptor wrapping changing timing.","solutions":["Check response.code() before trusting the progress totals; an error body will produce misleading byte counts.","Confirm the resource path still exists.","Only forward to your ProgressListener when response.isSuccessful() if you only care about success bodies.","Branch on the code instead of throwing so progress + status are both observable."],"exampleFix":"// before\ntry (Response response = client.newCall(request).execute()) {\n  if (!response.isSuccessful()) throw new IOException(\"Unexpected code \" + response);\n  System.out.println(response.body().string());\n}\n\n// after\ntry (Response response = client.newCall(request).execute()) {\n  if (!response.isSuccessful()) {\n    System.err.println(\"HTTP \" + response.code() + \" (progress totals were for the error body)\");\n    return;\n  }\n  System.out.println(response.body().string());\n}","handlingStrategy":"validation","validationCode":"// Only trust progress totals on success; check status first.\nif (!response.isSuccessful()) { /* error body; ignore progress totals */ return; }","typeGuard":"static boolean progressReflectsTarget(Response r, long expectedLength) {\n  return r.isSuccessful() && (r.body().contentLength() == -1 || r.body().contentLength() == expectedLength);\n}","tryCatchPattern":"try (Response r = client.newCall(request).execute()) {\n  if (!r.isSuccessful()) { /* status; progress listener reported error-body bytes */ return; }\n} catch (IOException e) {\n  // transport error\n}","preventionTips":["Check response.code() before trusting progress byte totals; error bodies mislead.","Confirm the resource path still exists.","Only forward to your listener when successful if you only care about success bodies.","Inspect contentLength() to validate the listener's reported length."],"tags":["okhttp","http-status","progress","interceptor","java"],"backgroundTag":null,"analyzedSha":"91a8b34c6f44bd28c421364f8edadc9f324dddd9","analyzedAt":"2026-08-10T18:39:54.316Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}