[Feature] Unify REST API response format for server, pd and store modules #2975#3029
[Feature] Unify REST API response format for server, pd and store modules #2975#3029BrandaoFelipe wants to merge 6 commits into
Conversation
|
I think the current implementation does not actually establish one unified runtime path yet. It adds new mappers/advice, but several existing paths either bypass them or now compete with them. Current shape: The main design issues are:
That makes the effective behavior unclear. If the new
I suggest first defining the response contract and then updating the existing runtime paths instead of adding parallel ones: One unrelated item: |
|
A larger concern is that this PR changes the public REST API response contract. The server / pd / store REST APIs may already be consumed by external services, so a large response-format change can have significant downstream impact. Current response shapes include fields such as: The new envelope introduces a different shape: That can break clients that parse existing fields like I think we should first decide the compatibility and migration strategy, for example: If this is intended to be a breaking change, it should probably go through community discussion and come with docs, migration notes, OpenAPI updates, and REST-level compatibility tests. If it is not intended to be breaking, then the implementation needs an explicit compatibility layer rather than replacing existing response bodies directly. In short: |
|
Hi @imbajin, Server: integrate the unified formatting into the existing ExceptionFilter infrastructure.
Do you think it would be better to continue this discussion in the PR thread, or would this be more appropriate for a broader dev mailing list discussion first? EDIT: |
|
IMO, a controller should only be responsible for receiving external requests and returning responses — exception handling logic does not belong there. We should remove the catch blocks from controllers and let a centralized handler take care of error formatting. For the store business code, rather than replacing it with the HTTP status code, we could simply add a dedicated field (e.g. That said, it's worth classifying controllers by their audience — user-facing, admin-facing, or internal module-facing. Internal module-facing interfaces may reasonably keep their existing response format unchanged, while the unified response format should at minimum be enforced across all user-facing endpoints. On compatibility: could we treat this as a breaking change and land it in the next major/minor version with proper release notes and migration guidance? |
Purpose of the PR
The purpose of this PR is to standardize and unify the REST API global error response format across the core modules (
pd,serverandstore/hg-store-node) using the centralizedApiResponseenvelope wrapper.Currently, unhandled exceptions or module-specific errors could return inconsistent formats or expose raw stack traces to the client. This tracking change enforces a clean, predictable JSON error contract across different frameworks used in the ecosystem (Jersey and Spring Boot), enhancing API security and client-side error handling.
Main Changes
This PR introduces centralized exception mapping logic across two distinct sub-framework layers within the project:
1.
hugegraph-servermodule (Jersey / JAX-RS)HugeExceptionMapper: Intercepts allHugeExceptionoccurrences. It safely resolves the underlying root cause using a recursiverootCause()lookup and maps internal core errors directly to appropriate HTTP Status Codes (e.g.,IllegalArgumentException-> 400 Bad Request,NoSuchElementException-> 404 Not Found) wrapped cleanly insideApiResponse.GenericExceptionMapper: Implemented as a top-level global catch-all provider forException.classto prevent infrastructure leakages, mapping unexpected exceptions to a secure HTTP 500"An unexpected error occurred"message payload.2.
hugegraph-storemodule (hg-store-nodesub-module / Spring Boot)StoreExceptionHandler: Created using Spring's@RestControllerAdviceto interceptHgStoreException. It dynamically parses the exception's internal errorcodeto differentiate client errors from infrastructure faults based on explicit ranges:[1200, 1300)(e.g., RocksDB storage failures) -> 500 Internal Server Error (logged asSEVERE/ERRORwith full stack trace).[1000, 1200)(e.g., Unsupported data formats) -> 400 Bad Request (logged cleanly as aWARNINGmessage).GenericExceptionMapper: Added as a fallback interceptor for standardException.classinstances inside the store node rest controllers to ensure uniform 500 error envelopes using the Log4j wrapper.3.
hugegraph-pdmodule (hg-pd-servicesub-module / Spring Boot)PdExceptionHandler: Implemented via@RestControllerAdviceto handle metadata and coordination cluster exceptions (PDException). Centralizes cluster control plane failure logging (Raft state, partition routing) and converts them into the unifiedApiResponseschema.Exception.classmapping to gracefully mask unhandled runtime infrastructure glitches with a generic"An unexpected error occurred in the cluster control plane"feedback text.Verifying these changes
mvn clean compile -DskipTestsfrom the root directory to confirm proper multi-module compile-time dependency alignment (validatingApiResponsecross-package visibility insidehg-store-node).{ "status": 400, "message": "Specific validation/error message string", "data": null, "statusText": "Bad Request" }Does this PR potentially affect the following parts?
Documentation Status
Doc - TODODoc - DoneDoc - No Need