Skip to content

[AI-8th]Add ProblemDetail (RFC 7807) support for standardized SOFABoot REST error responses#1418

Closed
pmupkin wants to merge 3 commits into
sofastack:masterfrom
pmupkin:migrate-spring-factories
Closed

[AI-8th]Add ProblemDetail (RFC 7807) support for standardized SOFABoot REST error responses#1418
pmupkin wants to merge 3 commits into
sofastack:masterfrom
pmupkin:migrate-spring-factories

Conversation

@pmupkin
Copy link
Copy Markdown

@pmupkin pmupkin commented Apr 23, 2026

This PR adds ProblemDetail support in sofa-boot-autoconfigure to standardize REST and SOFA RPC REST error responses based on RFC 7807.Related issue #1403

It includes:

  • Adding SofaProblemDetailAutoConfiguration and related configuration properties under sofa.boot.problem-detail.*
  • Introducing a shared SofaProblemDetailFactory to centralize exception-to-ProblemDetail mapping
  • Adding a Spring MVC @RestControllerAdvice to render SOFA exceptions as application/problem+json
  • Adding JAX-RS ExceptionMapper implementations for SOFA RPC REST scenarios, reusing the same problem detail mapping logic
  • Supporting extension fields such as errorCode, errorType, and service, with optional stackTrace exposure
    Integrating with MessageSource so title and detail can be localized
  • Adding tests for auto-configuration, MVC responses, JAX-RS mapping, compatibility behavior, and i18n

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds RFC 7807 ProblemDetail-based error rendering for SOFA RPC REST (Spring MVC + JAX-RS) and introduces Jakarta Bean Validation-based fail-fast validation for several SOFABoot @ConfigurationProperties.

Changes:

  • Introduce SofaProblemDetailAutoConfiguration + MVC @RestControllerAdvice + JAX-RS ExceptionMappers backed by a shared SofaProblemDetailFactory.
  • Add sofa.boot.problem-detail.* configuration properties (type base URI, stack trace/service info toggles, etc.) and tests for MVC/JAX-RS behavior and i18n.
  • Add Bean Validation annotations + validators and related tests to fail fast on invalid SOFABoot configuration properties; add spring-boot-starter-validation dependencies.

Reviewed changes

Copilot reviewed 27 out of 27 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
sofa-boot-project/sofaboot-dependencies/pom.xml Adds dependency management entry for spring-boot-starter-validation.
sofa-boot-project/sofa-boot-autoconfigure/pom.xml Adds spring-boot-starter-validation dependency to enable property validation.
sofa-boot-project/sofa-boot-actuator-autoconfigure/pom.xml Adds spring-boot-starter-validation dependency for actuator property validation.
sofa-boot-project/sofa-boot-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports Registers new SofaProblemDetailAutoConfiguration for auto-import.
sofa-boot-project/sofa-boot-autoconfigure/src/main/java/com/alipay/sofa/boot/autoconfigure/problem/SofaProblemDetailAutoConfiguration.java Auto-configures ProblemDetail factory + MVC advice + JAX-RS mappers/provider registration.
sofa-boot-project/sofa-boot-autoconfigure/src/main/java/com/alipay/sofa/boot/autoconfigure/problem/SofaProblemDetailProperties.java Adds sofa.boot.problem-detail.* properties (enabled, defaultType, typeBaseUri, etc.).
sofa-boot-project/sofa-boot-autoconfigure/src/main/java/com/alipay/sofa/boot/autoconfigure/problem/SofaProblemDetailFactory.java Centralizes exception-to-ProblemDetail mapping, rendering, and i18n resolution.
sofa-boot-project/sofa-boot-autoconfigure/src/main/java/com/alipay/sofa/boot/autoconfigure/problem/SofaProblemDetailExceptionHandler.java Spring MVC @RestControllerAdvice returning application/problem+json.
sofa-boot-project/sofa-boot-autoconfigure/src/main/java/com/alipay/sofa/boot/autoconfigure/problem/AbstractSofaProblemDetailExceptionMapper.java Base JAX-RS mapper to build problem+json responses using the shared factory.
sofa-boot-project/sofa-boot-autoconfigure/src/main/java/com/alipay/sofa/boot/autoconfigure/problem/SofaRpcExceptionProblemDetailExceptionMapper.java JAX-RS mapper for SofaRpcException.
sofa-boot-project/sofa-boot-autoconfigure/src/main/java/com/alipay/sofa/boot/autoconfigure/problem/SofaRpcRuntimeExceptionProblemDetailExceptionMapper.java JAX-RS mapper for SofaRpcRuntimeException.
sofa-boot-project/sofa-boot-autoconfigure/src/main/java/com/alipay/sofa/boot/autoconfigure/problem/SofaBootRpcRuntimeExceptionProblemDetailExceptionMapper.java JAX-RS mapper for SofaBootRpcRuntimeException.
sofa-boot-project/sofa-boot-autoconfigure/src/main/java/com/alipay/sofa/boot/autoconfigure/tracer/SofaTracerProperties.java Adds Bean Validation constraints and @Validated to tracer properties.
sofa-boot-project/sofa-boot-autoconfigure/src/main/java/com/alipay/sofa/boot/autoconfigure/runtime/SofaRuntimeProperties.java Adds @Validated and cross-field/assertion validation for executor sizing.
sofa-boot-project/sofa-boot-autoconfigure/src/main/java/com/alipay/sofa/boot/autoconfigure/isle/SofaModuleProperties.java Adds @Validated and positive constraints for parallel refresh settings.
sofa-boot-project/sofa-boot-actuator-autoconfigure/src/main/java/com/alipay/sofa/boot/actuator/autoconfigure/health/HealthProperties.java Adds @Validated and positive constraints for health timeout settings.
sofa-boot-project/sofa-boot-autoconfigure/src/main/java/com/alipay/sofa/boot/autoconfigure/rpc/SofaBootRpcProperties.java Enables @Validated and class-level constraint for RPC properties.
sofa-boot-project/sofa-boot-autoconfigure/src/main/java/com/alipay/sofa/boot/autoconfigure/rpc/ValidSofaBootRpcProperties.java Introduces class-level constraint annotation for RPC properties.
sofa-boot-project/sofa-boot-autoconfigure/src/main/java/com/alipay/sofa/boot/autoconfigure/rpc/SofaBootRpcPropertiesValidator.java Implements the class-level validator for RPC property combinations/ranges.
sofa-boot-project/sofa-boot-autoconfigure/src/test/java/com/alipay/sofa/boot/autoconfigure/problem/SofaProblemDetailAutoConfigurationTests.java Verifies auto-config backoff, JAX-RS provider registration, and stack trace toggle.
sofa-boot-project/sofa-boot-autoconfigure/src/test/java/com/alipay/sofa/boot/autoconfigure/problem/SofaProblemDetailMvcAutoConfigurationTests.java Verifies MVC problem+json output, i18n via MessageSource, ordering, stack trace toggle.
sofa-boot-project/sofa-boot-autoconfigure/src/test/java/com/alipay/sofa/boot/autoconfigure/rpc/SofaBootRpcPropertiesValidatorTests.java Unit tests for RPC properties validator behavior and edge cases.
sofa-boot-project/sofa-boot-autoconfigure/src/test/java/com/alipay/sofa/boot/autoconfigure/tracer/SofaTracerAutoConfigurationTests.java Adds fail-fast test for invalid tracer sampling percentage.
sofa-boot-project/sofa-boot-autoconfigure/src/test/java/com/alipay/sofa/boot/autoconfigure/runtime/SofaRuntimeAutoConfigurationTests.java Adds fail-fast test for invalid async init executor sizing.
sofa-boot-project/sofa-boot-autoconfigure/src/test/java/com/alipay/sofa/boot/autoconfigure/rpc/SofaRpcAutoConfigurationTests.java Adds fail-fast tests for invalid RPC properties.
sofa-boot-project/sofa-boot-autoconfigure/src/test/java/com/alipay/sofa/boot/autoconfigure/isle/SofaModuleAutoConfigurationTests.java Adds fail-fast test for invalid module parallel refresh factor.
sofa-boot-project/sofa-boot-actuator-autoconfigure/src/test/java/com/alipay/sofa/boot/actuator/autoconfigure/health/ReadinessAutoConfigurationTests.java Adds fail-fast test for invalid actuator health timeout configuration.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +42 to +43
*
* @author OpenAI
Copy link

Copilot AI Apr 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New classes in this module typically use a real contributor name/email in Javadoc @author tags (e.g., SofaRpcAutoConfiguration). Using OpenAI here is inconsistent with existing conventions; please replace with the actual contributor (or remove the tag if authorship isn’t tracked).

Suggested change
*
* @author OpenAI

Copilot uses AI. Check for mistakes.
Comment on lines +35 to +36
*
* @author OpenAI
Copy link

Copilot AI Apr 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New classes in this module typically use a real contributor name/email in Javadoc @author tags. Using OpenAI here is inconsistent with existing conventions; please replace with the actual contributor (or remove the tag).

Suggested change
*
* @author OpenAI

Copilot uses AI. Check for mistakes.
Comment on lines +21 to +28
import javax.ws.rs.ext.Provider;

/**
* JAX-RS mapper for {@link SofaRpcException}.
*
* @author OpenAI
*/
@Provider
Copy link

Copilot AI Apr 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JAX-RS providers in this codebase appear to be registered explicitly via JAXRSProviderManager.registerCustomProviderInstance(...) (see RestFilterConfiguration). Keeping @Provider here is redundant and risks double-registration if a JAX-RS runtime also performs classpath scanning. Consider removing @Provider and relying on the explicit registration mechanism.

Also, @author OpenAI is inconsistent with existing conventions in this repository; please use the actual contributor name/email (or omit the tag).

Suggested change
import javax.ws.rs.ext.Provider;
/**
* JAX-RS mapper for {@link SofaRpcException}.
*
* @author OpenAI
*/
@Provider
/**
* JAX-RS mapper for {@link SofaRpcException}.
*/

Copilot uses AI. Check for mistakes.
* @author OpenAI
*/
@AutoConfiguration(after = SofaRpcAutoConfiguration.class)
@ConditionalOnClass(ProblemDetail.class)
Copy link

Copilot AI Apr 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SofaProblemDetailAutoConfiguration is only conditional on ProblemDetail, but it always creates SofaProblemDetailFactory, which has hard references to SOFA RPC exception classes. In apps that include sofa-boot-autoconfigure but do not have rpc-sofa-boot / SOFA RPC on the classpath, this can trigger NoClassDefFoundError when the factory class is loaded. Consider adding an additional @ConditionalOnClass (or splitting configs) that gates this auto-configuration on the presence of the relevant SOFA RPC exception types (e.g., SofaRpcException / SofaRpcRuntimeException / SofaBootRpcRuntimeException).

Suggested change
@ConditionalOnClass(ProblemDetail.class)
@ConditionalOnClass(name = { "org.springframework.http.ProblemDetail",
"com.alipay.sofa.rpc.core.exception.SofaRpcException",
"com.alipay.sofa.rpc.core.exception.SofaRpcRuntimeException",
"com.alipay.sofa.boot.rpc.exception.SofaBootRpcRuntimeException" })

Copilot uses AI. Check for mistakes.
Comment on lines +38 to +39
*
* @author OpenAI
Copy link

Copilot AI Apr 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New classes in this module typically use a real contributor name/email in Javadoc @author tags (see other auto-configurations in this project). Using OpenAI here is inconsistent with existing conventions; please replace with the actual contributor (or remove the tag).

Suggested change
*
* @author OpenAI

Copilot uses AI. Check for mistakes.
Comment on lines +25 to +26
*
* @author OpenAI
Copy link

Copilot AI Apr 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New classes in this module typically use a real contributor name/email in Javadoc @author tags (see other auto-configurations in this project). Using OpenAI here is inconsistent with existing conventions; please replace with the actual contributor (or remove the tag).

Suggested change
*
* @author OpenAI

Copilot uses AI. Check for mistakes.
Comment on lines +33 to +34
*
* @author OpenAI
Copy link

Copilot AI Apr 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New classes in this module typically use a real contributor name/email in Javadoc @author tags. Using OpenAI here is inconsistent with existing conventions; please replace with the actual contributor (or remove the tag).

Suggested change
*
* @author OpenAI

Copilot uses AI. Check for mistakes.
Comment on lines +21 to +28
import javax.ws.rs.ext.Provider;

/**
* JAX-RS mapper for {@link SofaRpcRuntimeException}.
*
* @author OpenAI
*/
@Provider
Copy link

Copilot AI Apr 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JAX-RS providers in this codebase appear to be registered explicitly via JAXRSProviderManager.registerCustomProviderInstance(...) (see RestFilterConfiguration). Keeping @Provider here is redundant and risks double-registration if a JAX-RS runtime also performs classpath scanning. Consider removing @Provider and relying on the explicit registration mechanism.

Also, @author OpenAI is inconsistent with existing conventions in this repository; please use the actual contributor name/email (or omit the tag).

Suggested change
import javax.ws.rs.ext.Provider;
/**
* JAX-RS mapper for {@link SofaRpcRuntimeException}.
*
* @author OpenAI
*/
@Provider
/**
* JAX-RS mapper for {@link SofaRpcRuntimeException}.
*/

Copilot uses AI. Check for mistakes.
Comment on lines +21 to +28
import javax.ws.rs.ext.Provider;

/**
* JAX-RS mapper for {@link SofaBootRpcRuntimeException}.
*
* @author OpenAI
*/
@Provider
Copy link

Copilot AI Apr 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JAX-RS providers in this codebase appear to be registered explicitly via JAXRSProviderManager.registerCustomProviderInstance(...) (see RestFilterConfiguration). Keeping @Provider here is redundant and risks double-registration if a JAX-RS runtime also performs classpath scanning. Consider removing @Provider and relying on the explicit registration mechanism.

Also, @author OpenAI is inconsistent with existing conventions in this repository; please use the actual contributor name/email (or omit the tag).

Suggested change
import javax.ws.rs.ext.Provider;
/**
* JAX-RS mapper for {@link SofaBootRpcRuntimeException}.
*
* @author OpenAI
*/
@Provider
/**
* JAX-RS mapper for {@link SofaBootRpcRuntimeException}.
*/

Copilot uses AI. Check for mistakes.
}

private void appendCommonProperties(ProblemDetail problemDetail, Throwable throwable) {
problemDetail.setProperty("exception", throwable.getClass().getName());
Copy link

Copilot AI Apr 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

appendCommonProperties always adds the server-side exception class name into the RFC7807 response (exception). This can leak internal implementation details to clients even when include-stack-trace is disabled. Consider removing this field by default or gating it behind a dedicated opt-in property (similar to includeStackTrace).

Suggested change
problemDetail.setProperty("exception", throwable.getClass().getName());
// Intentionally left blank to avoid leaking internal exception class names
// in client-facing RFC7807 responses.

Copilot uses AI. Check for mistakes.
@pmupkin pmupkin closed this Apr 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants