Repository navigation
[ANCHOR-1413]: Enhance SEP-31 persistence and JSON mapping with error handling - #2092
Merged
Merged
Conversation
…han 255 characters
…pdates and fields past 255 characters
…ver every exception type and handler
… required_info_updates read-back
amandagonsalves
approved these changes
Nov 12, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
fieldsorrequired_info_updatesserialize to more than 255 characters are now created, patched and read back intact.sep31_transaction.fieldsand.required_info_updatesbecome nativeJSONcolumns (V37__sep31_json_columns.sql, sameALTER ... TYPE ... USINGform asV6and the SEP-6 precedent), andJdbcSep31Transactionmaps both with@JdbcTypeCode(SqlTypes.JSON)instead of string accessors.AbstractControllerExceptionHandler.handleInternalErroranswers HTTP 500 with{"error":"An internal error occurred."}when the exception, or anything in its cause chain, is aDataAccessException,TransactionException,PersistenceExceptionorSQLException. The full exception is still logged at ERROR and sent to Sentry. The cause-chain walk stops on a cycle. It applies to the SEP, Platform and Observer servers because they share the handler.Context
VARCHAR(255)fromV1__master.sqlwhile the entity writes JSON into them, so one moderately long field value (or a handful of fields) made the INSERT fail. The unhandled failure then returned the full parameterized INSERT and the column list ofsep31_transactionto any caller with a SEP-10 token. The SEP-6 columns for the same purpose were already converted toJSONin V10 and V36; SEP-31 never was.Testing
./gradlew test./gradlew :platform:testand./gradlew :platform:spotlessCheck :essential-tests:spotlessCheck: green.AbstractControllerExceptionHandlerTest(each persistence exception type, wrapped and cyclic chains, nothing leaked in the body, log and Sentry capture, the three advices, every specific handler unchanged),Sep31JsonMigrationTest(the migration alters exactly the two columns),JdbcSep31TransactionTest(JSON mapping and round trip).Sep31Tests(full class run on the local stack, 23 tests, 0 failures): POST with a 300-character value,fieldsof exactly 255 and 256 serialized characters, non-ASCII values, Platform API read-back, a PATCH merge past 255 characters, andrequired_info_updateswith descriptions, choices andoptionalflags read back.json, and all 142 rows are byte-identical. The same SQL on a seeded copy kept the textnull, SQLNULL, an object withchoicesand non-ASCII values. On a copy with a non-JSONfieldsvalue it fails and leaves the table unchanged.Documentation
N/A: no API contract or configuration changes; this fixes a failure for valid requests.
Known limitations
V37rewritessep31_transactionunder an exclusive lock (ALTER COLUMN ... TYPE), so large deployments should run it in a quiet window. There is no down migration; a row holding non-JSON text in either column makes the migration fail and roll back.BadRequestExceptionbuilt from a database error) is still echoed. Nothing in the SEP-31 write path builds one today. Both are candidates for a follow-up ticket.VARCHAR(255)columns ofsep31_transactionand other tables were not audited for the same overflow; one would now return the generic 500 but is not fixed here.fields: the existingmax_request_body_size(1 MiB, 413 above it) is the bound.