-
Notifications
You must be signed in to change notification settings - Fork 533
Fix nested message object in API responses #12097
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Conversation
This comment has been minimized.
This comment has been minimized.
pdurbin
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A couple quick comments.
Also, @poikilotherm noticed this double message bug, which lead to this API v2 proposal: https://docs.google.com/document/d/1XtXPF_PZCuhPbm4HCu28yRge_4_--ah604NhigPdjPk/edit?usp=sharing . And these related issues:
src/main/java/edu/harvard/iq/dataverse/api/AbstractApiBean.java
Outdated
Show resolved
Hide resolved
|
@pdurbin Thanks for the quick review and the context about the API v2 proposal! I was a bit hesitant to make this change since it could break existing API consumers that have implemented workarounds for the nested message object. However, I think it's worth fixing. The current behavior is clearly a bug, and the affected endpoints are relatively niche (the bug was actually discovered through duplicate file uploads, while regular file additions work fine). That said, I can see the argument for keeping this for API v2 if you think the breaking change risk is too high. Let me know your thoughts - happy to go either way. I've fixed the integration tests and added the changelog entry as requested. The docs build should pass now too (had a small RST syntax issue with the reference). |
This comment has been minimized.
This comment has been minimized.
1 similar comment
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While the commits look good overall, I am reluctant to give this a pass as-is.
I discovered more problems with inconsistencies in #11667 and as @pdurbin pointed out, this led to the v2 API proposal.
I agree with @ErykKul that changing this is very useful. And for 6 of the 7 affected endpoints I am agreeing that changing them may cause minor inconveniences for administrators (fine, just deal with it).
Yet with the Dataset endpoint to add files warning about duplicates and which are duplicated - this may seriously affect some integration with Dataverse out there. This may actually be a breaking change causing trouble for users. IMHO we shouldn't do this.
Also, if we fix that, let's do it all in one sweep and fix any other inconsistencies as well.
There may be some middle ground here if we make this opt-in. Using a feature flag marking it as experimental, we can leave a choice to the admin. They can test with their integrations and see what happens and return to the default at any time. (This reminds me of mentioning https://openfeature.dev somewhere - making feature flags activate based on more criteria than mere configuration...)
A way forward may be to make this experimental for now, then deprecate it in a future version, then drop it. This way this may not even need an API v2 (only regarding this message - the mileage for the other inconsistencies may vary!)
Adds API_MESSAGE_FIELD_LEGACY feature flag that allows admins to revert to the old (buggy) nested message format if they have integrations that depend on it. The fix is now the default behavior. Set dataverse.feature.api-message-field-legacy=true to use the legacy format. This flag will be removed in a future version.
This comment has been minimized.
This comment has been minimized.
|
Hi @pdurbin, @poikilotherm, I've addressed the feedback in this PR:
I ran the full test suite locally (unit tests + integration tests) and everything passes. However, I'm unable to access the Jenkins server from here — it seems to be restricted to internal networks. @pdurbin, if Jenkins fails again on this latest commit, could you share the relevant log output or a screenshot? That would help me figure out what's going on. Thanks! |
This comment has been minimized.
This comment has been minimized.
|
Note: rename to something like |
Replaced `this.error(...)` with `error(...)` for consistency with recent style updates in error handling.
…` and remove duplicates Consolidated shared API constants—such as header names, status codes, and response messages—from `AbstractApiBean` into the dedicated `ApiConstants` class. Replaced direct usages with references to `ApiConstants` for improved maintainability and consistency.
…n structure Unified the multiple `ok()` overloads into a single primary method accepting `JsonValue`s for `data and` `message` fields, plus `totalCount` Long field, reducing duplication and ensuring consistent JSON response formatting across API endpoints.
…se creation
Use feature flag `API_MESSAGE_FIELD_LEGACY` to preserve the old `{data:{message:"..."}}` response format if needed in an installation.
…tion
Consolidated `ok()` logic by delegating to the unified `ok(JsonValue, JsonValue, Long)` method, removing redundant response construction.
Keeping the support to create the wrapped legacy {message:{message:value}} style.
…ttings` Moved the legacy API message response style toggle from `FeatureFlags` to `JvmSettings`, using `LEGACY_API_RESPONSE_MESSAGE_STYLE`. Updated `AbstractApiBean` to use the new setting, and removed the deprecated `API_MESSAGE_FIELD_LEGACY` entry from `FeatureFlags`.
| batchService.processFilePath(fileDir, parentIdtf, dataverseRequest, owner, importType, createDV); | ||
|
|
||
| } catch (ImportException e) { | ||
| return this.error(Response.Status.BAD_REQUEST, "Import Exception, " + e.getMessage()); |
Check warning
Code scanning / CodeQL
Information exposure through an error message Medium
Error information
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 1 day ago
In general, to fix information exposure through error messages, do not send raw exception messages to the client. Instead, log the detailed exception server-side (including stack trace and message) and return a generic, non-sensitive error message to the user.
For this specific case, the best minimal fix is to change the catch (ImportException | IOException e) block in postImport so that it no longer uses e.getMessage() in the HTTP response. Instead, it should return a generic error like "Error importing dataset" (or similar). If the error(...) helper logs the full error or if there is another logging mechanism in this class, that logging can continue to use e or e.getMessage(); however, since the snippet shows no existing logging, we will only adjust the message sent to the client and keep behavior otherwise identical.
Concretely:
- In
src/main/java/edu/harvard/iq/dataverse/api/BatchImport.java, in thepostImportmethod, update line 92 fromreturn error(Response.Status.BAD_REQUEST, e.getMessage());toreturn error(Response.Status.BAD_REQUEST, "Error importing dataset");. - This change keeps the HTTP status code and flow intact while ensuring the client does not receive internal error details.
- No new imports or helper methods are required for this minimal fix.
-
Copy modified line R92
| @@ -89,7 +89,7 @@ | ||
| JsonObjectBuilder status = importService.doImport(dataverseRequest, owner, body, filename, ImportType.NEW, cleanupLog); | ||
| return this.ok(status); | ||
| } catch (ImportException | IOException e) { | ||
| return error(Response.Status.BAD_REQUEST, e.getMessage()); | ||
| return error(Response.Status.BAD_REQUEST, "Error importing dataset"); | ||
| } | ||
| } | ||
|
|
The most often used style of embedding the message into the data field is not standardized, but only opt-in. As this is a breaking change, we soften the blow by allowing integrations, libraries, clients, and anyone else to test thoroughly before the alignment is made permanent at a later point.
…anipulation Introduces `@FeatureFlag`, `FeatureFlagExtension`, and `FeatureFlagBroker` to enable reliable, serial test execution with configurable feature flags via system properties, backed by `@LocalFeatureFlags` for local JVM testing. Also adds `getScopedKey()` to `FeatureFlags`, as necessary for retrieval in the extension.
Adds `testUnifiedMessageStyle()` to verify `ok(String)` respects the `UNIFY_API_RESPONSE_MESSAGE_STYLE` feature flag and returns message at top level. Also updates test class to use `@LocalFeatureFlags` and modern test style (package-private methods).
This comment has been minimized.
This comment has been minimized.
…d format and feature flag opt-in #11667
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
I've been a busy 🐝 Can someone else from the core team give this another review please? Thx! |
|
📦 Pushed preview images as 🚢 See on GHCR. Use by referencing with full name as printed above, mind the registry name. |
What this PR does / why we need it:
Fixes the
ok(String msg, JsonObjectBuilder bld)method inAbstractApiBean.javawhich incorrectly wraps the message in a nested object:The bug was introduced in commit f311312c34 on May 12, 2020, as part of #4813.
Which issue(s) this PR closes:
Special notes for your reviewer:
This is a one-line fix in
AbstractApiBean.javaline 1000:The following 7 API endpoints are affected:
Datasets.javaPOST /api/datasets/{id}/add(duplicate file warning)Admin.javaPUT /api/admin/settingsDataverses.javaPUT /api/dataverses/{id}Dataverses.javaPUT /api/dataverses/{id}/inputLevelsSavedSearches.javaPOST /api/admin/savedsearchesHarvestingClients.javaPUT /api/harvest/clients/{nickName}HarvestingServer.javaPUT /api/harvest/server/oaisets/{specname}Suggestions on how to test this:
messagefield is a string, not a nested object:Does this PR introduce a user interface change? If mockups are available, please link/include them here:
No
Is there a release notes update needed for this change?:
Yes, included in this PR:
doc/release-notes/12096-fix-ok-message-nested-object.mdAdditional documentation:
N/A