{"record":{"id":"4a2898c300379842","repo":"pinpoint-apm/pinpoint","slug":"runtimeexception-wrapping-exception-from-getstatus","errorCode":null,"errorMessage":"RuntimeException wrapping Exception from getStatusCode","messagePattern":"RuntimeException wrapping Exception from getStatusCode","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"agent-module/plugins/spring-webflux/src/main/java/com/navercorp/pinpoint/plugin/spring/webflux/interceptor/util/Spring6HttpStatusProvider.java","lineNumber":31,"sourceCode":" * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.navercorp.pinpoint.plugin.spring.webflux.interceptor.util;\n\nimport org.springframework.http.client.reactive.ClientHttpResponse;\n\n/**\n * @author intr3p1d\n */\npublic class Spring6HttpStatusProvider implements HttpStatusProvider {\n    @Override\n    public int getStatusCode(Object target) {\n        if (target instanceof ClientHttpResponse) {\n            final ClientHttpResponse response = (ClientHttpResponse) target;\n            try {\n                return response.getStatusCode().value();\n            } catch (Exception e) {\n                throw new RuntimeException(e);\n            }\n        }\n        return -1;\n    }\n}\n","sourceCodeStart":13,"sourceCodeEnd":37,"githubUrl":"https://github.com/pinpoint-apm/pinpoint/blob/744c3d3075e595656abb1ae331ad2c0e4c9eb996/agent-module/plugins/spring-webflux/src/main/java/com/navercorp/pinpoint/plugin/spring/webflux/interceptor/util/Spring6HttpStatusProvider.java#L13-L37","documentation":"Spring6HttpStatusProvider.getStatusCode wraps any exception thrown while reading the HTTP status of a Spring 6 ClientHttpResponse into a plain RuntimeException. The library does this to satisfy the int-returning interceptor contract while surfacing that the response object could not provide a status code. The original cause (IOException, parse failure, etc.) is preserved as the cause.","triggerScenarios":"getStatusCode(Object) is called with a ClientHttpResponse whose getStatusCode() throws — typically because the underlying stream is already consumed/closed, the connection was reset, or the response is malformed.","commonSituations":"WebFlux instrumentation reading the status of a response whose body/stream was already consumed by the application; network interruption mid-response; calling getStatusCode twice on a streaming response that cannot re-read it.","solutions":["Inspect the cause (RuntimeException#getCause) to find the real I/O or parse failure","Ensure the interceptor is not consuming a response stream the application also reads — avoid double-reading ClientHttpResponse","Check network/proxy stability between client and server","Upgrade/verify the spring-web plugin version matches the application's Spring Framework 6.x version"],"exampleFix":"// before: raw wrap loses context handling\nthrow new RuntimeException(e);\n// after: keep interceptor contract but log the cause and return -1\ntry {\n    return response.getStatusCode().value();\n} catch (Exception e) {\n    logger.warn(\"failed to read status code\", e);\n    return -1;\n}","handlingStrategy":"try-catch","validationCode":"if (target instanceof ClientHttpResponse) {\n    ClientHttpResponse r = (ClientHttpResponse) target;\n    try {\n        r.getStatusCode();\n    } catch (Exception e) {\n        logger.warn(\"status code unreadable: {}\", e.getMessage());\n    }\n}","typeGuard":"boolean isReadableResponse(Object o) {\n    return o instanceof ClientHttpResponse;\n}","tryCatchPattern":"try {\n    int code = provider.getStatusCode(response);\n} catch (RuntimeException e) {\n    Throwable cause = e.getCause();\n    logger.warn(\"failed to read status code\", cause);\n    code = -1;\n}","preventionTips":["Never share one ClientHttpResponse stream between instrumentation and application code","Always inspect getCause() on this RuntimeException to find the real I/O error","Keep the spring-webflux plugin version aligned with the app's Spring version","Treat a -1 sentinel as 'status unavailable' and avoid retrying the read"],"tags":["http","spring-webflux","interceptor","exception-wrapping"],"backgroundTag":"http-request-failed","analyzedSha":"744c3d3075e595656abb1ae331ad2c0e4c9eb996","analyzedAt":"2026-09-07T18:48:45.289Z","contentChangedAt":"2026-09-07T18:48:45.289Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}