pinpoint-apm/pinpoint · warning

handleGeneralException

Error message

handleGeneralException: {}

What it means

CustomExceptionHandler.handleGeneralException is the catch-all @ExceptionHandler(Throwable.class) for the Pinpoint web REST API. Any unhandled exception reaching the controller layer is logged as a warning with its message and stack trace, then converted to an RFC-7807 ProblemDetail response (with status/headers from ErrorResponse when applicable, else a generic 500).

Solutions

  1. Read the logged stack trace to find the actual root exception in your endpoint call
  2. Add a specific @ExceptionHandler for the concrete exception type to return a proper status code
  3. Fix the client request (validate parameters before calling the API)
  4. File/fix a web bug if the exception originates from valid input

Example fix

// before
@ExceptionHandler({Throwable.class})
public ResponseEntity<ProblemDetail> handleGeneralException(Throwable ex, WebRequest request) {
    logger.warn("handleGeneralException: {}", ex.getMessage(), ex);
// after
@ExceptionHandler({Throwable.class})
public ResponseEntity<ProblemDetail> handleGeneralException(Throwable ex, WebRequest request) {
    logger.error("handleGeneralException: {}", ex.getMessage(), ex); // 5xx root causes deserve error level
    Throwable root = NestedExceptionUtils.getMostSpecificCause(ex);
    ...
Defensive patterns

Strategy: try-catch

Validate before calling

// validate request params before hitting the API
if (applicationName == null || applicationName.isBlank()) {
    throw new MissingRequiredParamException("applicationName");
}

Try / catch

try {
    ResponseEntity<ProblemDetail> resp = restTemplate.getForEntity(url, ProblemDetail.class);
} catch (HttpStatusCodeException e) {
    ProblemDetail body = e.getResponseBodyAs(ProblemDetail.class);
    logger.warn("API returned {}: {}", e.getStatusCode(), body != null ? body.getDetail() : e.getMessage());
}

Prevention

When it happens

Trigger: Any exception not matched by a more specific @ExceptionHandler — NPEs from malformed request data, service-layer failures, unexpected IllegalStateException, etc. — thrown inside web controller/service code.

Common situations: Malformed query parameters reaching service code; NPEs due to missing HBase data; bugs in recently added endpoints; ErrorResponse exceptions being handled here when no dedicated handler exists.

Related errors


AI-assisted analysis of pinpoint-apm/pinpoint@744c3d3075 (2026-09-07). Data as JSON: /api/errors/4adef0c76b618537. Report an issue: GitHub.

Appendix: source

Thrown at web/src/main/java/com/navercorp/pinpoint/web/problem/CustomExceptionHandler.java:88

    public CustomExceptionHandler(String hostname, ErrorProperties errorProperties) {
        this.hostname = Objects.requireNonNull(hostname, "hostname");
        this.errorProperties = Objects.requireNonNull(errorProperties, "errorProperties");
    }

    @ExceptionHandler({
            org.apache.catalina.connector.ClientAbortException.class
    })
    public ResponseEntity<Void> handleClientAbort(Exception ex) {
        logger.debug("Client disconnected: {}", ex.getMessage());
        return null;
    }

    @ExceptionHandler({Throwable.class})
    public ResponseEntity<ProblemDetail> handleGeneralException(
            Throwable ex,
            WebRequest request
    ) {
        logger.warn("handleGeneralException: {}", ex.getMessage(), ex);

        if (ex instanceof ErrorResponse errorResponse) {
            ProblemDetail problemDetail = errorResponse.getBody();
            addProperties(problemDetail, request);
            addStackTraces(problemDetail, ex);
            return new ResponseEntity<>(problemDetail, errorResponse.getHeaders(), errorResponse.getStatusCode());
        }
        HttpStatus status = HttpStatus.INTERNAL_SERVER_ERROR;
        ProblemDetail problemDetail = ProblemDetail.forStatus(status);
        problemDetail.setTitle(status.getReasonPhrase());
        problemDetail.setDetail(ex.getMessage());
        addProperties(problemDetail, request);
        addStackTraces(problemDetail, ex);

        return new ResponseEntity<>(problemDetail, status);
    }

    @ExceptionHandler(AccessDeniedException.class)

View on GitHub (pinned to 744c3d3075)