Skip to content

reject empty values in a mutation request body - #628

Merged
cportele merged 3 commits into
masterfrom
reject-empty-values
Sep 2, 2026
Merged

reject empty values in a mutation request body #628
cportele merged 3 commits into
masterfrom
reject-empty-values

Conversation

@cportele

@cportele cportele commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Part of ldproxy/ldproxy#1767.

A property element that is present but carries no value states an empty value.
The GML decoder dropped it, so an empty value could not be told apart from an
absent property anywhere downstream: it silently discarded what the document
said, and a request that set a property to nothing looked like one that left it
out. It is now decoded as an empty value, the way a JSON member with "" always
was.

Decoders can also reject such a value outright, for the input formats alike and
without a second parse of the content: a new event handler wraps the handler a
decoder emits to, next to the read-only one, and sees the values as the decoder
resolved them, so an element that carries its value in xlink:href and one that
states xsi:nil need no case of their own. A value the document omits, or states
as null, does not reach the handler and is unaffected.

The GML decoder no longer describes such a rejection as a parse failure — the
document parsed, only the value was rejected.

In addition, this PR removes the exception class name in a feature mutation error message:

The stream that decodes and encodes a mutation is run with join(), which wraps
a failure in a CompletionException whose message is the cause's toString() —
so every error reported for a failed action was prefixed with the class name of
the exception behind it. How the stream is run is nobody else's business, so the
wrapper no longer escapes the method that created it.

A cause that is itself wrapped now also reaches the encoder-error translation,
which turns a database or JSON parse failure into a message written for the
client instead of relaying the raw one.

A property element that is present but carries no value states an empty value.
The GML decoder dropped it, so an empty value could not be told apart from an
absent property anywhere downstream: it silently discarded what the document
said, and a request that set a property to nothing looked like one that left it
out. It is now decoded as an empty value, the way a JSON member with "" always
was.

Decoders can also reject such a value outright, for the input formats alike and
without a second parse of the content: a new event handler wraps the handler a
decoder emits to, next to the read-only one, and sees the values as the decoder
resolved them, so an element that carries its value in xlink:href and one that
states xsi:nil need no case of their own. A value the document omits, or states
as null, does not reach the handler and is unaffected.

The GML decoder no longer describes such a rejection as a parse failure — the
document parsed, only the value was rejected.
The stream that decodes and encodes a mutation is run with join(), which wraps
a failure in a CompletionException whose message is the cause's toString() —
so every error reported for a failed action was prefixed with the class name of
the exception behind it. How the stream is run is nobody else's business, so the
wrapper no longer escapes the method that created it.

A cause that is itself wrapped now also reaches the encoder-error translation,
which turns a database or JSON parse failure into a message written for the
client instead of relaying the raw one.
@cportele
cportele enabled auto-merge (squash) September 2, 2026 13:33
@cportele
cportele merged commit 5caa3b5 into master Sep 2, 2026
3 checks passed
@cportele
cportele deleted the reject-empty-values branch September 2, 2026 13:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants