pinpoint-apm/pinpoint · error · RuntimeException
RuntimeException wrapping Exception from getStatusCode
Error message
RuntimeException wrapping Exception from getStatusCode
What it means
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.
Source
Thrown at agent-module/plugins/spring-webflux/src/main/java/com/navercorp/pinpoint/plugin/spring/webflux/interceptor/util/Spring6HttpStatusProvider.java:31
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.navercorp.pinpoint.plugin.spring.webflux.interceptor.util;
import org.springframework.http.client.reactive.ClientHttpResponse;
/**
* @author intr3p1d
*/
public class Spring6HttpStatusProvider implements HttpStatusProvider {
@Override
public int getStatusCode(Object target) {
if (target instanceof ClientHttpResponse) {
final ClientHttpResponse response = (ClientHttpResponse) target;
try {
return response.getStatusCode().value();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
return -1;
}
}
View on GitHub (pinned to 744c3d3075)
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
Example fix
// before: raw wrap loses context handling
throw new RuntimeException(e);
// after: keep interceptor contract but log the cause and return -1
try {
return response.getStatusCode().value();
} catch (Exception e) {
logger.warn("failed to read status code", e);
return -1;
} Defensive patterns
Strategy: try-catch
Validate before calling
if (target instanceof ClientHttpResponse) {
ClientHttpResponse r = (ClientHttpResponse) target;
try {
r.getStatusCode();
} catch (Exception e) {
logger.warn("status code unreadable: {}", e.getMessage());
}
} Type guard
boolean isReadableResponse(Object o) {
return o instanceof ClientHttpResponse;
} Try / catch
try {
int code = provider.getStatusCode(response);
} catch (RuntimeException e) {
Throwable cause = e.getCause();
logger.warn("failed to read status code", cause);
code = -1;
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
Related errors
- execute fail. Error:
- not found interceptorHolderClass, className=
- not found interceptor, className=
- invocation fail, className=
- not found 'get' method, className=
AI-assisted analysis of pinpoint-apm/pinpoint@744c3d3075 (2026-09-07).
Data as JSON: /api/errors/4a2898c300379842.
Report an issue: GitHub.